passagemath-schemes 10.6.47__cp312-cp312-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
  9. passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list_nf.py +1241 -0
  154. sage/modular/modsym/relation_matrix.py +591 -0
  155. sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
  156. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  157. sage/modular/modsym/space.py +2468 -0
  158. sage/modular/modsym/subspace.py +455 -0
  159. sage/modular/modsym/tests.py +375 -0
  160. sage/modular/multiple_zeta.py +2632 -0
  161. sage/modular/multiple_zeta_F_algebra.py +786 -0
  162. sage/modular/overconvergent/all.py +6 -0
  163. sage/modular/overconvergent/genus0.py +1878 -0
  164. sage/modular/overconvergent/hecke_series.py +1187 -0
  165. sage/modular/overconvergent/weightspace.py +778 -0
  166. sage/modular/pollack_stevens/all.py +4 -0
  167. sage/modular/pollack_stevens/distributions.py +874 -0
  168. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  169. sage/modular/pollack_stevens/manin_map.py +859 -0
  170. sage/modular/pollack_stevens/modsym.py +1593 -0
  171. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  172. sage/modular/pollack_stevens/sigma0.py +534 -0
  173. sage/modular/pollack_stevens/space.py +1076 -0
  174. sage/modular/quasimodform/all.py +3 -0
  175. sage/modular/quasimodform/element.py +845 -0
  176. sage/modular/quasimodform/ring.py +828 -0
  177. sage/modular/quatalg/all.py +3 -0
  178. sage/modular/quatalg/brandt.py +1642 -0
  179. sage/modular/ssmod/all.py +8 -0
  180. sage/modular/ssmod/ssmod.py +827 -0
  181. sage/rings/all__sagemath_schemes.py +1 -0
  182. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  183. sage/rings/polynomial/binary_form_reduce.py +585 -0
  184. sage/schemes/all.py +41 -0
  185. sage/schemes/berkovich/all.py +6 -0
  186. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  187. sage/schemes/berkovich/berkovich_space.py +748 -0
  188. sage/schemes/curves/affine_curve.py +2928 -0
  189. sage/schemes/curves/all.py +33 -0
  190. sage/schemes/curves/closed_point.py +434 -0
  191. sage/schemes/curves/constructor.py +381 -0
  192. sage/schemes/curves/curve.py +542 -0
  193. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  194. sage/schemes/curves/point.py +463 -0
  195. sage/schemes/curves/projective_curve.py +3026 -0
  196. sage/schemes/curves/zariski_vankampen.py +1932 -0
  197. sage/schemes/cyclic_covers/all.py +2 -0
  198. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  199. sage/schemes/cyclic_covers/constructor.py +137 -0
  200. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  201. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  202. sage/schemes/elliptic_curves/BSD.py +1036 -0
  203. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  204. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  205. sage/schemes/elliptic_curves/all.py +49 -0
  206. sage/schemes/elliptic_curves/cardinality.py +609 -0
  207. sage/schemes/elliptic_curves/cm.py +1102 -0
  208. sage/schemes/elliptic_curves/constructor.py +1552 -0
  209. sage/schemes/elliptic_curves/ec_database.py +175 -0
  210. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  211. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  212. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  213. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  214. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  215. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  216. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  217. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  218. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  219. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  220. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  221. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  222. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  223. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  224. sage/schemes/elliptic_curves/formal_group.py +760 -0
  225. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  226. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  227. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  228. sage/schemes/elliptic_curves/heegner.py +7335 -0
  229. sage/schemes/elliptic_curves/height.py +2109 -0
  230. sage/schemes/elliptic_curves/hom.py +1406 -0
  231. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  232. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  233. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  234. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  235. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  236. sage/schemes/elliptic_curves/homset.py +271 -0
  237. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  238. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  239. sage/schemes/elliptic_curves/jacobian.py +237 -0
  240. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  241. sage/schemes/elliptic_curves/kraus.py +1014 -0
  242. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  243. sage/schemes/elliptic_curves/mod5family.py +105 -0
  244. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  245. sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
  246. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  247. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  248. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  249. sage/schemes/elliptic_curves/padics.py +1816 -0
  250. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  251. sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
  252. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  253. sage/schemes/elliptic_curves/saturation.py +715 -0
  254. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  255. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  256. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  257. sage/schemes/hyperelliptic_curves/all.py +6 -0
  258. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  259. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  260. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  261. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  264. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  265. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  266. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  267. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  270. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  271. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  272. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  273. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  274. sage/schemes/jacobians/all.py +2 -0
  275. sage/schemes/overview.py +161 -0
  276. sage/schemes/plane_conics/all.py +22 -0
  277. sage/schemes/plane_conics/con_field.py +1296 -0
  278. sage/schemes/plane_conics/con_finite_field.py +158 -0
  279. sage/schemes/plane_conics/con_number_field.py +456 -0
  280. sage/schemes/plane_conics/con_rational_field.py +406 -0
  281. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  282. sage/schemes/plane_conics/constructor.py +249 -0
  283. sage/schemes/plane_quartics/all.py +2 -0
  284. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  285. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  286. sage/schemes/riemann_surfaces/all.py +1 -0
  287. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  288. sage_wheels/share/cremona/cremona_mini.db +0 -0
  289. sage_wheels/share/ellcurves/rank0 +30427 -0
  290. sage_wheels/share/ellcurves/rank1 +31871 -0
  291. sage_wheels/share/ellcurves/rank10 +6 -0
  292. sage_wheels/share/ellcurves/rank11 +6 -0
  293. sage_wheels/share/ellcurves/rank12 +1 -0
  294. sage_wheels/share/ellcurves/rank14 +1 -0
  295. sage_wheels/share/ellcurves/rank15 +1 -0
  296. sage_wheels/share/ellcurves/rank17 +1 -0
  297. sage_wheels/share/ellcurves/rank19 +1 -0
  298. sage_wheels/share/ellcurves/rank2 +2388 -0
  299. sage_wheels/share/ellcurves/rank20 +1 -0
  300. sage_wheels/share/ellcurves/rank21 +1 -0
  301. sage_wheels/share/ellcurves/rank22 +1 -0
  302. sage_wheels/share/ellcurves/rank23 +1 -0
  303. sage_wheels/share/ellcurves/rank24 +1 -0
  304. sage_wheels/share/ellcurves/rank28 +1 -0
  305. sage_wheels/share/ellcurves/rank3 +836 -0
  306. sage_wheels/share/ellcurves/rank4 +10 -0
  307. sage_wheels/share/ellcurves/rank5 +5 -0
  308. sage_wheels/share/ellcurves/rank6 +5 -0
  309. sage_wheels/share/ellcurves/rank7 +5 -0
  310. sage_wheels/share/ellcurves/rank8 +6 -0
  311. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,2017 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ """
3
+ Hypergeometric motives
4
+
5
+ This is largely a port of the corresponding package in Magma. One
6
+ important conventional difference: the motivic parameter `t` has been replaced
7
+ with `1/t` to match the classical literature on hypergeometric series.
8
+ (E.g., see [BeukersHeckman]_)
9
+
10
+ The computation of Euler factors is currently only supported for primes `p`
11
+ of good or tame reduction.
12
+
13
+ AUTHORS:
14
+
15
+ - Frédéric Chapoton
16
+ - Kiran S. Kedlaya
17
+
18
+ EXAMPLES::
19
+
20
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
21
+ sage: H = Hyp(cyclotomic=([30], [1,2,3,5]))
22
+ sage: H.alpha_beta()
23
+ ([1/30, 7/30, 11/30, 13/30, 17/30, 19/30, 23/30, 29/30],
24
+ [0, 1/5, 1/3, 2/5, 1/2, 3/5, 2/3, 4/5])
25
+ sage: H.M_value() == 30**30 / (15**15 * 10**10 * 6**6)
26
+ True
27
+ sage: H.euler_factor(2, 7)
28
+ T^8 + T^5 + T^3 + 1
29
+
30
+ REFERENCES:
31
+
32
+ - [BeukersHeckman]_
33
+
34
+ - [Benasque2009]_
35
+
36
+ - [Kat1991]_
37
+
38
+ - [MagmaHGM]_
39
+
40
+ - [Fedorov2015]_
41
+
42
+ - [Roberts2017]_
43
+
44
+ - [Roberts2015]_
45
+
46
+ - [RRV2022]_
47
+
48
+ - [BeCoMe]_
49
+
50
+ - [Watkins]_
51
+ """
52
+ # ****************************************************************************
53
+ # Copyright (C) 2017--2024 Frédéric Chapoton
54
+ # Kiran S. Kedlaya <kskedl@gmail.com>
55
+ #
56
+ # Distributed under the terms of the GNU General Public License (GPL)
57
+ # as published by the Free Software Foundation; either version 2 of
58
+ # the License, or (at your option) any later version.
59
+ #
60
+ # https://www.gnu.org/licenses/
61
+ # ****************************************************************************
62
+
63
+ from collections import defaultdict
64
+ from itertools import combinations
65
+ from sage.arith.misc import divisors, gcd, euler_phi, is_prime, moebius
66
+ from sage.arith.misc import gauss_sum, kronecker_symbol
67
+ from sage.combinat.integer_vector_weighted import WeightedIntegerVectors
68
+ from sage.functions.generalized import sgn
69
+ from sage.functions.log import log
70
+ from sage.functions.other import floor, ceil, frac
71
+ from sage.geometry.lattice_polytope import LatticePolytope
72
+ from sage.matrix.constructor import matrix
73
+ from sage.misc.cachefunc import cached_method
74
+ from sage.misc.functional import cyclotomic_polynomial
75
+ from sage.misc.lazy_import import lazy_import
76
+ from sage.misc.misc_c import prod
77
+ from sage.modular.hypergeometric_misc import hgm_coeffs
78
+ from sage.modules.free_module_element import vector
79
+ from sage.rings.finite_rings.finite_field_constructor import GF
80
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
81
+ from sage.rings.fraction_field import FractionField
82
+ from sage.rings.integer_ring import ZZ
83
+ from sage.rings.padics.factory import Zp
84
+ from sage.rings.padics.padic_generic_element import gauss_table
85
+ from sage.rings.polynomial.polynomial_ring import polygen, polygens
86
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
87
+ from sage.rings.power_series_ring import PowerSeriesRing
88
+ from sage.rings.rational_field import QQ
89
+ from sage.schemes.generic.spec import Spec
90
+
91
+ lazy_import('sage.rings.universal_cyclotomic_field', 'UniversalCyclotomicField')
92
+
93
+
94
+ def characteristic_polynomial_from_traces(traces, d, q, i, sign, deg=None, use_fe=True):
95
+ r"""
96
+ Given a sequence of traces `t_1, \dots, t_k`, return the
97
+ corresponding characteristic polynomial with Weil numbers as roots.
98
+
99
+ The characteristic polynomial is defined by the generating series
100
+
101
+ .. MATH::
102
+
103
+ P(T) = \exp\left(- \sum_{k\geq 1} t_k \frac{T^k}{k}\right)
104
+
105
+ and should have the property that reciprocals of all roots have
106
+ absolute value `q^{i/2}`.
107
+
108
+ INPUT:
109
+
110
+ - ``traces`` -- list of integers `t_1, \dots, t_k`
111
+
112
+ - ``d`` -- the degree of the characteristic polynomial
113
+
114
+ - ``q`` -- power of a prime number
115
+
116
+ - ``i`` -- integer; the weight in the motivic sense
117
+
118
+ - ``sign`` -- integer; the sign
119
+
120
+ - ``deg`` -- integer or ``None``
121
+
122
+ - ``use_fe`` -- boolean (default: ``True``)
123
+
124
+ OUTPUT: a polynomial
125
+
126
+ If ``deg`` is specified, only the coefficients up to this degree (inclusive) are computed.
127
+
128
+ If ``use_fe`` is ``False``, we ignore the local functional equation.
129
+
130
+ EXAMPLES::
131
+
132
+ sage: from sage.modular.hypergeometric_motive import characteristic_polynomial_from_traces
133
+ sage: characteristic_polynomial_from_traces([1, 1], 1, 3, 0, -1)
134
+ -T + 1
135
+ sage: characteristic_polynomial_from_traces([25], 1, 5, 4, -1)
136
+ -25*T + 1
137
+
138
+ sage: characteristic_polynomial_from_traces([3], 2, 5, 1, 1)
139
+ 5*T^2 - 3*T + 1
140
+ sage: characteristic_polynomial_from_traces([1], 2, 7, 1, 1)
141
+ 7*T^2 - T + 1
142
+
143
+ sage: characteristic_polynomial_from_traces([20], 3, 29, 2, 1)
144
+ 24389*T^3 - 580*T^2 - 20*T + 1
145
+ sage: characteristic_polynomial_from_traces([12], 3, 13, 2, -1)
146
+ -2197*T^3 + 156*T^2 - 12*T + 1
147
+
148
+ sage: characteristic_polynomial_from_traces([36, 7620], 4, 17, 3, 1)
149
+ 24137569*T^4 - 176868*T^3 - 3162*T^2 - 36*T + 1
150
+ sage: characteristic_polynomial_from_traces([-4, 276], 4, 5, 3, 1)
151
+ 15625*T^4 + 500*T^3 - 130*T^2 + 4*T + 1
152
+ sage: characteristic_polynomial_from_traces([4, -276], 4, 5, 3, 1)
153
+ 15625*T^4 - 500*T^3 + 146*T^2 - 4*T + 1
154
+ sage: characteristic_polynomial_from_traces([22, 484], 4, 31, 2, -1)
155
+ -923521*T^4 + 21142*T^3 - 22*T + 1
156
+
157
+ sage: characteristic_polynomial_from_traces([22], 4, 31, 2, -1, deg=1)
158
+ -22*T + 1
159
+ sage: characteristic_polynomial_from_traces([22, 484], 4, 31, 2, -1, deg=4)
160
+ -923521*T^4 + 21142*T^3 - 22*T + 1
161
+
162
+ TESTS::
163
+
164
+ sage: characteristic_polynomial_from_traces([-36], 4, 17, 3, 1)
165
+ Traceback (most recent call last):
166
+ ...
167
+ ValueError: not enough traces were given
168
+ """
169
+ if use_fe:
170
+ bound = d // 2 if deg is None else min(d // 2, deg)
171
+ else:
172
+ bound = d if deg is None else min(d, deg)
173
+ if len(traces) < bound:
174
+ raise ValueError('not enough traces were given')
175
+ if i % 2 and d % 2 and use_fe:
176
+ raise ValueError('i and d may not both be odd')
177
+ t = PowerSeriesRing(QQ, 't').gen()
178
+ ring = PolynomialRing(ZZ, 'T')
179
+
180
+ series = sum(- api * t**(i + 1) / (i + 1) for i, api in enumerate(traces))
181
+ series = series.O(bound + 1).exp()
182
+ coeffs = list(series)
183
+ coeffs += [0] * max(0, bound + 1 - len(coeffs))
184
+
185
+ fulldeg = d if deg is None else deg
186
+ data = [0] * (fulldeg + 1)
187
+ for k in range(bound + 1):
188
+ data[k] = coeffs[k]
189
+ for k in range(bound + 1, fulldeg + 1):
190
+ data[k] = sign * coeffs[d - k] * q**(i * (k - d / 2))
191
+ return ring(data)
192
+
193
+
194
+ def enumerate_hypergeometric_data(d, weight=None):
195
+ r"""
196
+ Return an iterator over parameters of hypergeometric motives (up to swapping).
197
+
198
+ INPUT:
199
+
200
+ - ``d`` -- the degree
201
+
202
+ - ``weight`` -- (optional) integer; specifies the motivic weight
203
+
204
+ EXAMPLES::
205
+
206
+ sage: from sage.modular.hypergeometric_motive import enumerate_hypergeometric_data as enum
207
+ sage: l = [H for H in enum(6, weight=2) if H.hodge_numbers()[0] == 1] # needs sage.combinat
208
+ sage: len(l) # needs sage.combinat
209
+ 112
210
+ """
211
+ bound = 2 * d * d # to make sure that phi(n) <= d
212
+ possible = [(i, euler_phi(i)) for i in range(1, bound + 1)
213
+ if euler_phi(i) <= d]
214
+ poids = [z[1] for z in possible]
215
+ N = len(poids)
216
+ vectors = WeightedIntegerVectors(d, poids)
217
+
218
+ def formule(u):
219
+ return [possible[j][0] for j in range(N) for _ in range(u[j])]
220
+
221
+ for a, b in combinations(vectors, 2):
222
+ if not any(a[j] and b[j] for j in range(N)):
223
+ H = HypergeometricData(cyclotomic=(formule(a), formule(b)))
224
+ if weight is None or H.weight() == weight:
225
+ yield H
226
+
227
+
228
+ def possible_hypergeometric_data(d, weight=None) -> list:
229
+ """
230
+ Return the list of possible parameters of hypergeometric motives (up to swapping).
231
+
232
+ INPUT:
233
+
234
+ - ``d`` -- the degree
235
+
236
+ - ``weight`` -- (optional) integer; specifies the motivic weight
237
+
238
+ EXAMPLES::
239
+
240
+ sage: from sage.modular.hypergeometric_motive import possible_hypergeometric_data as P
241
+ sage: [len(P(i, weight=2)) for i in range(1, 7)] # needs sage.combinat
242
+ [0, 0, 10, 30, 93, 234]
243
+ """
244
+ return list(enumerate_hypergeometric_data(d, weight))
245
+
246
+
247
+ def cyclotomic_to_alpha(cyclo) -> list:
248
+ """
249
+ Convert a list of indices of cyclotomic polynomials
250
+ to a list of rational numbers.
251
+
252
+ The input represents a product of cyclotomic polynomials.
253
+
254
+ The output is the list of arguments of the roots of the
255
+ given product of cyclotomic polynomials.
256
+
257
+ This is the inverse of :func:`alpha_to_cyclotomic`.
258
+
259
+ EXAMPLES::
260
+
261
+ sage: from sage.modular.hypergeometric_motive import cyclotomic_to_alpha
262
+ sage: cyclotomic_to_alpha([1])
263
+ [0]
264
+ sage: cyclotomic_to_alpha([2])
265
+ [1/2]
266
+ sage: cyclotomic_to_alpha([5])
267
+ [1/5, 2/5, 3/5, 4/5]
268
+ sage: cyclotomic_to_alpha([1, 2, 3, 6])
269
+ [0, 1/6, 1/3, 1/2, 2/3, 5/6]
270
+ sage: cyclotomic_to_alpha([2, 3])
271
+ [1/3, 1/2, 2/3]
272
+ """
273
+ alpha = [QQ((k, d)) for d in cyclo
274
+ for k in ZZ(d).coprime_integers(d)]
275
+ return sorted(alpha)
276
+
277
+
278
+ def alpha_to_cyclotomic(alpha) -> list:
279
+ """
280
+ Convert from a list of rationals arguments to a list of integers.
281
+
282
+ The input represents arguments of some roots of unity.
283
+
284
+ The output represent a product of cyclotomic polynomials with exactly
285
+ the given roots. Note that the multiplicity of `r/s` in the list
286
+ must be independent of `r`; otherwise, a :exc:`ValueError` will be raised.
287
+
288
+ This is the inverse of :func:`cyclotomic_to_alpha`.
289
+
290
+ EXAMPLES::
291
+
292
+ sage: from sage.modular.hypergeometric_motive import alpha_to_cyclotomic
293
+ sage: alpha_to_cyclotomic([0])
294
+ [1]
295
+ sage: alpha_to_cyclotomic([1/2])
296
+ [2]
297
+ sage: alpha_to_cyclotomic([1/5, 2/5, 3/5, 4/5])
298
+ [5]
299
+ sage: alpha_to_cyclotomic([0, 1/6, 1/3, 1/2, 2/3, 5/6])
300
+ [1, 2, 3, 6]
301
+ sage: alpha_to_cyclotomic([1/3, 2/3, 1/2])
302
+ [2, 3]
303
+ """
304
+ cyclo = []
305
+ Alpha = list(alpha)
306
+ while Alpha:
307
+ q = QQ(Alpha.pop())
308
+ n = q.numerator()
309
+ d = q.denominator()
310
+ for k in d.coprime_integers(d):
311
+ if k != n:
312
+ try:
313
+ Alpha.remove(QQ((k, d)))
314
+ except ValueError:
315
+ raise ValueError("multiplicities not balanced")
316
+ cyclo.append(d)
317
+ return sorted(cyclo)
318
+
319
+
320
+ def capital_M(n):
321
+ """
322
+ Auxiliary function, used to describe the canonical scheme.
323
+
324
+ INPUT:
325
+
326
+ - ``n`` -- integer
327
+
328
+ OUTPUT: a rational
329
+
330
+ EXAMPLES::
331
+
332
+ sage: from sage.modular.hypergeometric_motive import capital_M
333
+ sage: [capital_M(i) for i in range(1, 8)]
334
+ [1, 4, 27, 64, 3125, 432, 823543]
335
+ """
336
+ n = ZZ(n)
337
+ return QQ.prod(d ** (d * moebius(n // d)) for d in divisors(n))
338
+
339
+
340
+ def cyclotomic_to_gamma(cyclo_up, cyclo_down) -> dict:
341
+ """
342
+ Convert a quotient of products of cyclotomic polynomials
343
+ to a quotient of products of polynomials `x^n - 1`.
344
+
345
+ INPUT:
346
+
347
+ - ``cyclo_up`` -- list of indices of cyclotomic polynomials in the numerator
348
+ - ``cyclo_down`` -- list of indices of cyclotomic polynomials in the denominator
349
+
350
+ OUTPUT:
351
+
352
+ a dictionary mapping an integer `n` to the power of `x^n - 1` that
353
+ appears in the given product
354
+
355
+ EXAMPLES::
356
+
357
+ sage: from sage.modular.hypergeometric_motive import cyclotomic_to_gamma
358
+ sage: cyclotomic_to_gamma([6], [1])
359
+ {2: -1, 3: -1, 6: 1}
360
+ """
361
+ dico: dict[int, int] = defaultdict(int)
362
+ for d in cyclo_up:
363
+ dico[d] += 1
364
+ for d in cyclo_down:
365
+ dico[d] -= 1
366
+
367
+ resu: dict[int, int] = defaultdict(int)
368
+ for n in dico:
369
+ for d in divisors(n):
370
+ resu[d] += moebius(n // d) * dico[n]
371
+
372
+ return {d: resu[d] for d in resu if resu[d]}
373
+
374
+
375
+ def gamma_list_to_cyclotomic(galist):
376
+ r"""
377
+ Convert a quotient of products of polynomials `x^n - 1`
378
+ to a quotient of products of cyclotomic polynomials.
379
+
380
+ INPUT:
381
+
382
+ - ``galist`` -- list of integers, where an integer `n` represents
383
+ the power `(x^{|n|} - 1)^{\operatorname{sgn}(n)}`
384
+
385
+ OUTPUT:
386
+
387
+ a pair of list of integers, where `k` represents the cyclotomic
388
+ polynomial `\Phi_k`
389
+
390
+ EXAMPLES::
391
+
392
+ sage: from sage.modular.hypergeometric_motive import gamma_list_to_cyclotomic
393
+ sage: gamma_list_to_cyclotomic([-1, -1, 2])
394
+ ([2], [1])
395
+
396
+ sage: gamma_list_to_cyclotomic([-1, -1, -1, -3, 6])
397
+ ([2, 6], [1, 1, 1])
398
+
399
+ sage: gamma_list_to_cyclotomic([-1, 2, 3, -4])
400
+ ([3], [4])
401
+
402
+ sage: gamma_list_to_cyclotomic([8, 2, 2, 2, -6, -4, -3, -1])
403
+ ([2, 2, 8], [3, 3, 6])
404
+ """
405
+ resu: dict[int, int] = defaultdict(int)
406
+ for n in galist:
407
+ eps = sgn(n)
408
+ for d in divisors(abs(n)):
409
+ resu[d] += eps
410
+
411
+ return (sorted(d for d in resu for k in range(resu[d])),
412
+ sorted(d for d in resu for k in range(-resu[d])))
413
+
414
+
415
+ class HypergeometricData:
416
+ _gauss_table = {}
417
+
418
+ def __init__(self, cyclotomic=None, alpha_beta=None, gamma_list=None):
419
+ r"""
420
+ Creation of hypergeometric motives.
421
+
422
+ INPUT:
423
+
424
+ Three possibilities are offered, each describing a quotient
425
+ of products of cyclotomic polynomials.
426
+
427
+ - ``cyclotomic`` -- a pair of lists of nonnegative integers,
428
+ each integer `k` represents a cyclotomic polynomial `\Phi_k`
429
+
430
+ - ``alpha_beta`` -- a pair of lists of rationals,
431
+ each rational represents a root of unity
432
+
433
+ - ``gamma_list`` -- a pair of lists of nonnegative integers,
434
+ each integer `n` represents a polynomial `x^n - 1`
435
+
436
+ In the last case, it is also allowed to send just one list of signed
437
+ integers where signs indicate to which part the integer belongs to.
438
+
439
+ EXAMPLES::
440
+
441
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
442
+ sage: Hyp(cyclotomic=([2], [1]))
443
+ Hypergeometric data for [1/2] and [0]
444
+
445
+ sage: Hyp(alpha_beta=([1/2], [0]))
446
+ Hypergeometric data for [1/2] and [0]
447
+ sage: Hyp(alpha_beta=([1/5,2/5,3/5,4/5], [0,0,0,0]))
448
+ Hypergeometric data for [1/5, 2/5, 3/5, 4/5] and [0, 0, 0, 0]
449
+
450
+ sage: Hyp(gamma_list=([5], [1,1,1,1,1]))
451
+ Hypergeometric data for [1/5, 2/5, 3/5, 4/5] and [0, 0, 0, 0]
452
+ sage: Hyp(gamma_list=([5,-1,-1,-1,-1,-1]))
453
+ Hypergeometric data for [1/5, 2/5, 3/5, 4/5] and [0, 0, 0, 0]
454
+ """
455
+ if gamma_list is not None:
456
+ if isinstance(gamma_list[0], (list, tuple)):
457
+ pos, neg = gamma_list
458
+ gamma_list = pos + [-u for u in neg]
459
+ cyclotomic = gamma_list_to_cyclotomic(gamma_list)
460
+ if cyclotomic is not None:
461
+ cyclo_up, cyclo_down = cyclotomic
462
+ if any(x in cyclo_up for x in cyclo_down):
463
+ raise ValueError('overlapping parameters not allowed')
464
+ deg = sum(euler_phi(x) for x in cyclo_down)
465
+ up_deg = sum(euler_phi(x) for x in cyclo_up)
466
+ if up_deg != deg:
467
+ msg = f'not the same degree: {up_deg} != {deg}'
468
+ raise ValueError(msg)
469
+ cyclo_up.sort()
470
+ cyclo_down.sort()
471
+ alpha = cyclotomic_to_alpha(cyclo_up)
472
+ beta = cyclotomic_to_alpha(cyclo_down)
473
+ elif alpha_beta is not None:
474
+ alpha, beta = alpha_beta
475
+ if len(alpha) != len(beta):
476
+ raise ValueError('alpha and beta not of the same length')
477
+ alpha = sorted(u - floor(u) for u in alpha)
478
+ beta = sorted(u - floor(u) for u in beta)
479
+ cyclo_up = alpha_to_cyclotomic(alpha)
480
+ cyclo_down = alpha_to_cyclotomic(beta)
481
+ deg = sum(euler_phi(x) for x in cyclo_down)
482
+
483
+ self._cyclo_up = tuple(cyclo_up)
484
+ self._cyclo_down = tuple(cyclo_down)
485
+ self._alpha = tuple(alpha)
486
+ self._beta = tuple(beta)
487
+ self._deg = deg
488
+ self._gamma_array = cyclotomic_to_gamma(cyclo_up, cyclo_down)
489
+ self._trace_coeffs = {}
490
+ up = QQ.prod(capital_M(d) for d in cyclo_up)
491
+ down = QQ.prod(capital_M(d) for d in cyclo_down)
492
+ self._M_value = up / down
493
+ if 0 in alpha:
494
+ self._swap = HypergeometricData(alpha_beta=(beta, alpha))
495
+ if self.weight() % 2:
496
+ self._sign_param = 1
497
+ else:
498
+ if (deg % 2) != (0 in alpha):
499
+ self._sign_param = prod(cyclotomic_polynomial(v).disc()
500
+ for v in cyclo_down)
501
+ else:
502
+ self._sign_param = prod(cyclotomic_polynomial(v).disc()
503
+ for v in cyclo_up)
504
+
505
+ # --- Internals ---
506
+ def __repr__(self) -> str:
507
+ """
508
+ Return the string representation.
509
+
510
+ This displays the rational arguments of the roots of unity.
511
+
512
+ EXAMPLES::
513
+
514
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
515
+ sage: Hyp(alpha_beta=([1/2],[0]))
516
+ Hypergeometric data for [1/2] and [0]
517
+ """
518
+ txt = "Hypergeometric data for {} and {}"
519
+ return txt.format(list(self._alpha), list(self._beta))
520
+
521
+ def __eq__(self, other) -> bool:
522
+ """
523
+ Return whether two data are equal.
524
+
525
+ EXAMPLES::
526
+
527
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
528
+ sage: H1 = Hyp(alpha_beta=([1/2], [0]))
529
+ sage: H2 = Hyp(cyclotomic=([6,2], [1,1,1]))
530
+ sage: H1 == H1
531
+ True
532
+ sage: H1 == H2
533
+ False
534
+ """
535
+ return (self._alpha == other._alpha and
536
+ self._beta == other._beta)
537
+
538
+ def __ne__(self, other) -> bool:
539
+ """
540
+ Return whether two data are unequal.
541
+
542
+ EXAMPLES::
543
+
544
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
545
+ sage: H1 = Hyp(alpha_beta=([1/2], [0]))
546
+ sage: H2 = Hyp(cyclotomic=([6,2], [1,1,1]))
547
+ sage: H1 != H1
548
+ False
549
+ sage: H1 != H2
550
+ True
551
+ """
552
+ return not (self == other)
553
+
554
+ def __hash__(self):
555
+ """
556
+ Return a hash for ``self``.
557
+
558
+ EXAMPLES::
559
+
560
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
561
+ sage: H1 = Hyp(alpha_beta=([1/2], [0]))
562
+ sage: h = hash(H1)
563
+ """
564
+ return hash((self._alpha, self._beta))
565
+
566
+ # --- Parameters and invariants ---
567
+ def cyclotomic_data(self) -> tuple:
568
+ """
569
+ Return the pair of tuples of indices of cyclotomic polynomials.
570
+
571
+ EXAMPLES::
572
+
573
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
574
+ sage: Hyp(alpha_beta=([1/2], [0])).cyclotomic_data()
575
+ ([2], [1])
576
+ """
577
+ return (list(self._cyclo_up), list(self._cyclo_down))
578
+
579
+ def alpha_beta(self) -> tuple:
580
+ """
581
+ Return the pair of lists of rational arguments.
582
+
583
+ EXAMPLES::
584
+
585
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
586
+ sage: Hyp(alpha_beta=([1/2], [0])).alpha_beta()
587
+ ([1/2], [0])
588
+ """
589
+ return (list(self._alpha), list(self._beta))
590
+
591
+ def alpha(self) -> list:
592
+ """
593
+ Return the first tuple of rational arguments.
594
+
595
+ EXAMPLES::
596
+
597
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
598
+ sage: Hyp(alpha_beta=([1/2], [0])).alpha()
599
+ [1/2]
600
+ """
601
+ return list(self._alpha)
602
+
603
+ def beta(self) -> list:
604
+ """
605
+ Return the second tuple of rational arguments.
606
+
607
+ EXAMPLES::
608
+
609
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
610
+ sage: Hyp(alpha_beta=([1/2], [0])).beta()
611
+ [0]
612
+ """
613
+ return list(self._beta)
614
+
615
+ def defining_polynomials(self) -> tuple:
616
+ """
617
+ Return the pair of products of cyclotomic polynomials.
618
+
619
+ EXAMPLES::
620
+
621
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
622
+ sage: Hyp(alpha_beta=([1/4,3/4], [0,0])).defining_polynomials()
623
+ (x^2 + 1, x^2 - 2*x + 1)
624
+ """
625
+ up = prod(cyclotomic_polynomial(d) for d in self._cyclo_up)
626
+ down = prod(cyclotomic_polynomial(d) for d in self._cyclo_down)
627
+ return (up, down)
628
+
629
+ def gamma_array(self) -> dict:
630
+ r"""
631
+ Return the dictionary `\{v: \gamma_v\}` for the expression
632
+
633
+ .. MATH::
634
+
635
+ \prod_v (T^v - 1)^{\gamma_v}
636
+
637
+ EXAMPLES::
638
+
639
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
640
+ sage: Hyp(alpha_beta=([1/2], [0])).gamma_array()
641
+ {1: -2, 2: 1}
642
+ sage: Hyp(cyclotomic=([6,2], [1,1,1])).gamma_array()
643
+ {1: -3, 3: -1, 6: 1}
644
+ """
645
+ return dict(self._gamma_array)
646
+
647
+ def gamma_list(self) -> list:
648
+ r"""
649
+ Return a list of integers describing the `x^n - 1` factors.
650
+
651
+ Each integer `n` stands for `(x^{|n|} - 1)^{\operatorname{sgn}(n)}`.
652
+
653
+ EXAMPLES::
654
+
655
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
656
+ sage: Hyp(alpha_beta=([1/2], [0])).gamma_list()
657
+ [-1, -1, 2]
658
+
659
+ sage: Hyp(cyclotomic=([6,2], [1,1,1])).gamma_list()
660
+ [-1, -1, -1, -3, 6]
661
+
662
+ sage: Hyp(cyclotomic=([3], [4])).gamma_list()
663
+ [-1, 2, 3, -4]
664
+ """
665
+ gamma = self.gamma_array()
666
+ resu = []
667
+ for v, n in sorted(gamma.items()):
668
+ resu += [sgn(n) * v] * abs(n)
669
+ return resu
670
+
671
+ def wild_primes(self) -> list:
672
+ r"""
673
+ Return the wild primes.
674
+
675
+ EXAMPLES::
676
+
677
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
678
+ sage: Hyp(cyclotomic=([3], [4])).wild_primes()
679
+ [2, 3]
680
+ sage: Hyp(cyclotomic=([2,2,2,2,3,3,3,6,6], [1,1,4,5,9])).wild_primes()
681
+ [2, 3, 5]
682
+ """
683
+ gamma = self.gamma_array()
684
+ return sorted({p for n in gamma for p, _ in n.factor()})
685
+
686
+ def zigzag(self, x, flip_beta=False):
687
+ r"""
688
+ Count ``alpha``'s at most ``x`` minus ``beta``'s at most ``x``.
689
+
690
+ This function is used to compute the weight and the Hodge numbers.
691
+ With ``flip_beta`` set to ``True``, replace each `b` in `\beta`
692
+ with `1-b`.
693
+
694
+ .. SEEALSO::
695
+
696
+ :meth:`weight`, :meth:`hodge_numbers`
697
+
698
+ EXAMPLES::
699
+
700
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
701
+ sage: H = Hyp(alpha_beta=([1/6,1/3,2/3,5/6], [1/8,3/8,5/8,7/8]))
702
+ sage: [H.zigzag(x) for x in [0, 1/3, 1/2]]
703
+ [0, 1, 0]
704
+ sage: H = Hyp(cyclotomic=([5], [1,1,1,1]))
705
+ sage: [H.zigzag(x) for x in [0,1/6,1/4,1/2,3/4,5/6]]
706
+ [-4, -4, -3, -2, -1, 0]
707
+ """
708
+ alpha = self._alpha
709
+ beta = self._beta
710
+ if flip_beta:
711
+ return (sum(1 for a in alpha if a <= x) -
712
+ sum(1 for b in beta if 1 - b <= x))
713
+ return (sum(1 for a in alpha if a <= x) -
714
+ sum(1 for b in beta if b <= x))
715
+
716
+ def weight(self):
717
+ """
718
+ Return the motivic weight of this motivic data.
719
+
720
+ EXAMPLES:
721
+
722
+ With rational inputs::
723
+
724
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
725
+ sage: Hyp(alpha_beta=([1/2], [0])).weight()
726
+ 0
727
+ sage: Hyp(alpha_beta=([1/4,3/4], [0,0])).weight()
728
+ 1
729
+ sage: Hyp(alpha_beta=([1/6,1/3,2/3,5/6], [0,0,1/4,3/4])).weight()
730
+ 1
731
+ sage: H = Hyp(alpha_beta=([1/6,1/3,2/3,5/6], [1/8,3/8,5/8,7/8]))
732
+ sage: H.weight()
733
+ 1
734
+
735
+ With cyclotomic inputs::
736
+
737
+ sage: Hyp(cyclotomic=([6,2], [1,1,1])).weight()
738
+ 2
739
+ sage: Hyp(cyclotomic=([6], [1,2])).weight()
740
+ 0
741
+ sage: Hyp(cyclotomic=([8], [1,2,3])).weight()
742
+ 0
743
+ sage: Hyp(cyclotomic=([5], [1,1,1,1])).weight()
744
+ 3
745
+ sage: Hyp(cyclotomic=([5,6], [1,1,2,2,3])).weight()
746
+ 1
747
+ sage: Hyp(cyclotomic=([3,8], [1,1,1,2,6])).weight()
748
+ 2
749
+ sage: Hyp(cyclotomic=([3,3], [2,2,4])).weight()
750
+ 1
751
+
752
+ With gamma list input::
753
+
754
+ sage: Hyp(gamma_list=([8,2,2,2], [6,4,3,1])).weight()
755
+ 3
756
+ """
757
+ alpha = self._alpha
758
+ beta = self._beta
759
+ D = [self.zigzag(x) for x in alpha + beta]
760
+ return ZZ(max(D) - min(D) - 1)
761
+
762
+ def degree(self):
763
+ """
764
+ Return the degree.
765
+
766
+ This is the sum of the Hodge numbers.
767
+
768
+ .. SEEALSO::
769
+
770
+ :meth:`hodge_numbers`
771
+
772
+ EXAMPLES::
773
+
774
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
775
+ sage: Hyp(alpha_beta=([1/2], [0])).degree()
776
+ 1
777
+ sage: Hyp(gamma_list=([2,2,4], [8])).degree()
778
+ 4
779
+ sage: Hyp(cyclotomic=([5,6], [1,1,2,2,3])).degree()
780
+ 6
781
+ sage: Hyp(cyclotomic=([3,8], [1,1,1,2,6])).degree()
782
+ 6
783
+ sage: Hyp(cyclotomic=([3,3], [2,2,4])).degree()
784
+ 4
785
+ """
786
+ return self._deg
787
+
788
+ def hodge_numbers(self) -> list:
789
+ """
790
+ Return the Hodge numbers.
791
+
792
+ .. SEEALSO::
793
+
794
+ :meth:`degree`, :meth:`hodge_polynomial`, :meth:`hodge_polygon`
795
+
796
+ EXAMPLES::
797
+
798
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
799
+ sage: H = Hyp(cyclotomic=([3], [6]))
800
+ sage: H.hodge_numbers()
801
+ [1, 1]
802
+
803
+ sage: H = Hyp(cyclotomic=([4], [1,2]))
804
+ sage: H.hodge_numbers()
805
+ [2]
806
+
807
+ sage: H = Hyp(gamma_list=([8,2,2,2], [6,4,3,1]))
808
+ sage: H.hodge_numbers()
809
+ [1, 2, 2, 1]
810
+
811
+ sage: H = Hyp(gamma_list=([5], [1,1,1,1,1]))
812
+ sage: H.hodge_numbers()
813
+ [1, 1, 1, 1]
814
+
815
+ sage: H = Hyp(gamma_list=[6,1,-4,-3])
816
+ sage: H.hodge_numbers()
817
+ [1, 1]
818
+
819
+ sage: H = Hyp(gamma_list=[-3]*4 + [1]*12)
820
+ sage: H.hodge_numbers()
821
+ [1, 1, 1, 1, 1, 1, 1, 1]
822
+
823
+ REFERENCES:
824
+
825
+ - [Fedorov2015]_
826
+ """
827
+ alpha = [(x, 'a') for x in self._alpha]
828
+ beta = [(x, 'b') for x in self._beta]
829
+ height = 0
830
+ hodge: dict[int, int] = defaultdict(int)
831
+ for x, letter in sorted(alpha + beta):
832
+ if letter == 'a':
833
+ hodge[height] += 1
834
+ height += 1
835
+ else:
836
+ height -= 1
837
+ return [hodge[i] for i in sorted(hodge)]
838
+
839
+ def hodge_polynomial(self):
840
+ """
841
+ Return the Hodge polynomial.
842
+
843
+ .. SEEALSO::
844
+
845
+ :meth:`hodge_numbers`, :meth:`hodge_polygon_vertices`, :meth:`hodge_function`
846
+
847
+ EXAMPLES::
848
+
849
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
850
+ sage: H = Hyp(cyclotomic=([6,10], [3,12]))
851
+ sage: H.hodge_polynomial()
852
+ (T^3 + 2*T^2 + 2*T + 1)/T^2
853
+ sage: H = Hyp(cyclotomic=([2,2,2,2,3,3,3,6,6], [1,1,4,5,9]))
854
+ sage: H.hodge_polynomial()
855
+ (T^5 + 3*T^4 + 3*T^3 + 3*T^2 + 3*T + 1)/T^2
856
+ """
857
+ alpha = self._alpha
858
+
859
+ def z(x):
860
+ return alpha.count(x)
861
+
862
+ T = polygen(ZZ, 'T')
863
+ return sum(T ** (self.zigzag(a, flip_beta=True) - z(a)) *
864
+ (T**z(a) - 1) // (T - 1)
865
+ for a in set(alpha))
866
+
867
+ def hodge_function(self, x):
868
+ """
869
+ Evaluate the Hodge polygon as a function.
870
+
871
+ .. SEEALSO::
872
+
873
+ :meth:`hodge_numbers`, :meth:`hodge_polynomial`, :meth:`hodge_polygon_vertices`
874
+
875
+ EXAMPLES::
876
+
877
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
878
+ sage: H = Hyp(cyclotomic=([6,10], [3,12]))
879
+ sage: H.hodge_function(3)
880
+ 2
881
+ sage: H.hodge_function(4)
882
+ 4
883
+ """
884
+ d = self.degree()
885
+ hn = self.hodge_numbers()
886
+ if x < 0:
887
+ return 0
888
+ i = 0
889
+ j = 0
890
+ k = 0
891
+ while (i < d and i < x):
892
+ i += hn[k]
893
+ j += k * hn[k]
894
+ k += 1
895
+ if i < x:
896
+ return j
897
+ return j - (i - x) * (k - 1)
898
+
899
+ def hodge_polygon_vertices(self) -> list:
900
+ """
901
+ Return the vertices of the Hodge polygon.
902
+
903
+ .. SEEALSO::
904
+
905
+ :meth:`hodge_numbers`, :meth:`hodge_polynomial`, :meth:`hodge_function`
906
+
907
+ EXAMPLES::
908
+
909
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
910
+ sage: H = Hyp(cyclotomic=([6,10], [3,12]))
911
+ sage: H.hodge_polygon_vertices()
912
+ [(0, 0), (1, 0), (3, 2), (5, 6), (6, 9)]
913
+ sage: H = Hyp(cyclotomic=([2,2,2,2,3,3,3,6,6], [1,1,4,5,9]))
914
+ sage: H.hodge_polygon_vertices()
915
+ [(0, 0), (1, 0), (4, 3), (7, 9), (10, 18), (13, 30), (14, 35)]
916
+ """
917
+ lst = [(0, 0)]
918
+ hn = self.hodge_numbers()
919
+ for i in range(len(hn)):
920
+ lst.append((lst[-1][0] + hn[i], lst[-1][1] + i * hn[i]))
921
+ return lst
922
+
923
+ def E_polynomial(self, vars=None):
924
+ """
925
+ Return the E-polynomial of ``self``.
926
+
927
+ This is a bivariate polynomial.
928
+
929
+ The algorithm is taken from [FRV2019]_.
930
+
931
+ INPUT:
932
+
933
+ - ``vars`` -- (optional) pair of variables (default: `u,v`)
934
+
935
+ REFERENCES:
936
+
937
+ .. [FRV2019] Fernando Rodriguez Villegas, *Mixed Hodge numbers
938
+ and factorial ratios*, :arxiv:`1907.02722`
939
+
940
+ EXAMPLES::
941
+
942
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData
943
+ sage: H = HypergeometricData(gamma_list=[-30, -1, 6, 10, 15])
944
+ sage: H.E_polynomial()
945
+ 8*u*v + 7*u + 7*v + 8
946
+
947
+ sage: p, q = polygens(QQ,'p,q')
948
+ sage: H.E_polynomial((p, q))
949
+ 8*p*q + 7*p + 7*q + 8
950
+
951
+ sage: H = HypergeometricData(gamma_list=(-11, -2, 1, 3, 4, 5))
952
+ sage: H.E_polynomial()
953
+ 5*u^2*v + 5*u*v^2 + u*v + 1
954
+
955
+ sage: H = HypergeometricData(gamma_list=(-63, -8, -2, 1, 4, 16, 21, 31))
956
+ sage: H.E_polynomial()
957
+ 21*u^3*v^2 + 21*u^2*v^3 + u^3*v + 23*u^2*v^2 + u*v^3 + u^2*v + u*v^2 + 2*u*v + 1
958
+ """
959
+ gamma = self.gamma_list()
960
+ ell = len(gamma)
961
+
962
+ gamma_plus = [g for g in gamma if g > 0]
963
+ gamma_minus = [g for g in gamma if g < 0]
964
+
965
+ domain = {d for g in gamma for d in divisors(g.abs())}
966
+
967
+ m_plus = {d: len([1 for g in gamma_plus if not g % d])
968
+ for d in domain}
969
+
970
+ m_minus = {d: len([1 for g in gamma_minus if not g % d])
971
+ for d in domain}
972
+
973
+ if vars is None:
974
+ u, v = polygens(ZZ, 'u,v')
975
+ else:
976
+ u, v = vars
977
+ uqv = u / v
978
+ uv = u * v
979
+
980
+ A = u.parent()
981
+ delta_sharp_N = {d: A.sum(uqv**sum(frac(j * gi / d) for gi in gamma)
982
+ for j in d.coprime_integers(d))
983
+ for d in domain}
984
+
985
+ loop = [(d, m_plus[d], m_minus[d]) for d in domain]
986
+
987
+ delta_sharp = sum((uqv**m - uqv**p) // (uqv - 1) * v**(ell - 1)
988
+ * delta_sharp_N[d]
989
+ for d, p, m in loop if m > p)
990
+
991
+ delta_zero = sum((uv**min(m, p) - 1) // (uv - 1) * v**(ell - m - p)
992
+ * delta_sharp_N[d]
993
+ for d, p, m in loop)
994
+
995
+ return (delta_sharp + delta_zero - 1).numerator() // (u * v)
996
+
997
+ def M_value(self):
998
+ """
999
+ Return the `M` coefficient that appears in the trace formula.
1000
+
1001
+ OUTPUT: a rational
1002
+
1003
+ .. SEEALSO:: :meth:`canonical_scheme`
1004
+
1005
+ EXAMPLES::
1006
+
1007
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1008
+ sage: H = Hyp(alpha_beta=([1/6,1/3,2/3,5/6], [1/8,3/8,5/8,7/8]))
1009
+ sage: H.M_value()
1010
+ 729/4096
1011
+ sage: Hyp(alpha_beta=(([1/2,1/2,1/2,1/2], [0,0,0,0]))).M_value()
1012
+ 256
1013
+ sage: Hyp(cyclotomic=([5], [1,1,1,1])).M_value()
1014
+ 3125
1015
+ """
1016
+ return self._M_value
1017
+
1018
+ def is_primitive(self) -> bool:
1019
+ """
1020
+ Return whether this data is primitive.
1021
+
1022
+ .. SEEALSO::
1023
+
1024
+ :meth:`primitive_index`, :meth:`primitive_data`
1025
+
1026
+ EXAMPLES::
1027
+
1028
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1029
+ sage: Hyp(cyclotomic=([3], [4])).is_primitive()
1030
+ True
1031
+ sage: Hyp(gamma_list=[-2, 4, 6, -8]).is_primitive()
1032
+ False
1033
+ sage: Hyp(gamma_list=[-3, 6, 9, -12]).is_primitive()
1034
+ False
1035
+ """
1036
+ return self.primitive_index() == 1
1037
+
1038
+ def primitive_index(self):
1039
+ """
1040
+ Return the primitive index.
1041
+
1042
+ .. SEEALSO::
1043
+
1044
+ :meth:`is_primitive`, :meth:`primitive_data`
1045
+
1046
+ EXAMPLES::
1047
+
1048
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1049
+ sage: Hyp(cyclotomic=([3], [4])).primitive_index()
1050
+ 1
1051
+ sage: Hyp(gamma_list=[-2, 4, 6, -8]).primitive_index()
1052
+ 2
1053
+ sage: Hyp(gamma_list=[-3, 6, 9, -12]).primitive_index()
1054
+ 3
1055
+ """
1056
+ return gcd(self.gamma_list())
1057
+
1058
+ def has_symmetry_at_one(self) -> bool:
1059
+ """
1060
+ If ``True``, the motive H(t=1) is a direct sum of two motives.
1061
+
1062
+ Note that simultaneous exchange of (t,1/t) and (alpha,beta)
1063
+ always gives the same motive.
1064
+
1065
+ EXAMPLES::
1066
+
1067
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1068
+ sage: Hyp(alpha_beta=[[1/2]*16, [0]*16]).has_symmetry_at_one()
1069
+ True
1070
+
1071
+ REFERENCES:
1072
+
1073
+ - [Roberts2017]_
1074
+ """
1075
+ beta_twist = self.twist()._beta
1076
+ return self.degree() % 2 == 0 and self._alpha == beta_twist
1077
+
1078
+ def lfunction(self, t, prec=53):
1079
+ """
1080
+ Return the `L`-function of ``self``.
1081
+
1082
+ The result is a wrapper around a PARI `L`-function.
1083
+
1084
+ INPUT:
1085
+
1086
+ - ``prec`` -- precision (default: 53)
1087
+
1088
+ EXAMPLES::
1089
+
1090
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1091
+ sage: H = Hyp(cyclotomic=([3], [4]))
1092
+ sage: L = H.lfunction(1/64); L
1093
+ PARI L-function associated to Hypergeometric data for [1/3, 2/3] and [1/4, 3/4]
1094
+ sage: L(4)
1095
+ 0.997734256321692
1096
+ """
1097
+ from sage.lfunctions.pari import lfun_hgm, LFunction
1098
+ Z = LFunction(lfun_hgm(self, t), prec=prec)
1099
+ Z.rename('PARI L-function associated to %s' % self)
1100
+ return Z
1101
+
1102
+ def canonical_scheme(self, t=None):
1103
+ """
1104
+ Return the canonical scheme.
1105
+
1106
+ This is a scheme that contains this hypergeometric motive in its cohomology.
1107
+
1108
+ EXAMPLES::
1109
+
1110
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1111
+ sage: H = Hyp(cyclotomic=([3], [4]))
1112
+ sage: H.gamma_list()
1113
+ [-1, 2, 3, -4]
1114
+ sage: H.canonical_scheme()
1115
+ Spectrum of Quotient of Multivariate Polynomial Ring
1116
+ in X0, X1, Y0, Y1 over Fraction Field of Univariate Polynomial Ring
1117
+ in t over Rational Field by the ideal
1118
+ (X0 + X1 - 1, Y0 + Y1 - 1, (-t)*X0^2*X1^3 + 27/64*Y0*Y1^4)
1119
+
1120
+ sage: H = Hyp(gamma_list=[-2, 3, 4, -5])
1121
+ sage: H.canonical_scheme()
1122
+ Spectrum of Quotient of Multivariate Polynomial Ring
1123
+ in X0, X1, Y0, Y1 over Fraction Field of Univariate Polynomial Ring
1124
+ in t over Rational Field by the ideal
1125
+ (X0 + X1 - 1, Y0 + Y1 - 1, (-t)*X0^3*X1^4 + 1728/3125*Y0^2*Y1^5)
1126
+
1127
+ REFERENCES:
1128
+
1129
+ [Kat1991]_, section 5.4
1130
+ """
1131
+ if t is None:
1132
+ t = FractionField(QQ['t']).gen()
1133
+ basering = t.parent()
1134
+ gamma_pos = [u for u in self.gamma_list() if u > 0]
1135
+ gamma_neg = [u for u in self.gamma_list() if u < 0]
1136
+ N_pos = len(gamma_pos)
1137
+ N_neg = len(gamma_neg)
1138
+ varX = [f'X{i}' for i in range(N_pos)]
1139
+ varY = [f'Y{i}' for i in range(N_neg)]
1140
+ ring = PolynomialRing(basering, varX + varY)
1141
+ gens = ring.gens()
1142
+ X = gens[:N_pos]
1143
+ Y = gens[N_pos:]
1144
+ eq0 = ring.sum(X) - 1
1145
+ eq1 = ring.sum(Y) - 1
1146
+ eq2_pos = ring.prod(X[i] ** gamma_pos[i] for i in range(N_pos))
1147
+ eq2_neg = ring.prod(Y[j] ** -gamma_neg[j] for j in range(N_neg))
1148
+
1149
+ ideal = ring.ideal([eq0, eq1, self.M_value() * eq2_neg - t * eq2_pos])
1150
+ return Spec(ring.quotient(ideal))
1151
+
1152
+ def lattice_polytope(self):
1153
+ """
1154
+ Return the associated lattice polytope.
1155
+
1156
+ This uses the matrix defined in section 3 of [RRV2022]_ and
1157
+ section 3 of [RV2019]_.
1158
+
1159
+ EXAMPLES::
1160
+
1161
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1162
+ sage: H = Hyp(gamma_list=[-5, -2, 3, 4])
1163
+ sage: P = H.lattice_polytope(); P
1164
+ 2-d lattice polytope in 2-d lattice M
1165
+ sage: P.polyhedron().f_vector()
1166
+ (1, 4, 4, 1)
1167
+ sage: len(P.points()) # needs palp
1168
+ 7
1169
+
1170
+ The Chebyshev example from [RV2019]_::
1171
+
1172
+ sage: H = Hyp(gamma_list=[-30, -1, 6, 10, 15])
1173
+ sage: P = H.lattice_polytope(); P
1174
+ 3-d lattice polytope in 3-d lattice M
1175
+ sage: len(P.points()) # needs palp
1176
+ 19
1177
+ sage: P.polyhedron().f_vector()
1178
+ (1, 5, 9, 6, 1)
1179
+ """
1180
+ l = len(self.gamma_list())
1181
+ m = matrix(ZZ, l, 1, self.gamma_list())
1182
+ ext_ker = m.kernel().basis_matrix().insert_row(0, vector(ZZ, [1] * l))
1183
+ unique_relation = ext_ker.kernel().basis()[0]
1184
+ removed = next(i for i, ci in enumerate(unique_relation)
1185
+ if i and abs(ci) == 1)
1186
+ mat = matrix(ZZ, [v for i, v in enumerate(ext_ker)
1187
+ if i and i != removed])
1188
+ return LatticePolytope(mat.transpose())
1189
+
1190
+ # --- Operations on data ---
1191
+ def twist(self):
1192
+ r"""
1193
+ Return the twist of this data.
1194
+
1195
+ This is defined by adding `1/2` to each rational in `\alpha`
1196
+ and `\beta`.
1197
+
1198
+ This is an involution.
1199
+
1200
+ EXAMPLES::
1201
+
1202
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1203
+ sage: H = Hyp(alpha_beta=([1/2], [0]))
1204
+ sage: H.twist()
1205
+ Hypergeometric data for [0] and [1/2]
1206
+ sage: H.twist().twist() == H
1207
+ True
1208
+
1209
+ sage: Hyp(cyclotomic=([6], [1,2])).twist().cyclotomic_data()
1210
+ ([3], [1, 2])
1211
+ """
1212
+ alpha = [x + QQ((1, 2)) for x in self._alpha]
1213
+ beta = [x + QQ((1, 2)) for x in self._beta]
1214
+ return HypergeometricData(alpha_beta=(alpha, beta))
1215
+
1216
+ def swap_alpha_beta(self):
1217
+ """
1218
+ Return the hypergeometric data with ``alpha`` and ``beta`` exchanged.
1219
+
1220
+ EXAMPLES::
1221
+
1222
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1223
+ sage: H = Hyp(alpha_beta=([1/2], [0]))
1224
+ sage: H.swap_alpha_beta()
1225
+ Hypergeometric data for [0] and [1/2]
1226
+ """
1227
+ alpha, beta = self.alpha_beta()
1228
+ return HypergeometricData(alpha_beta=(beta, alpha))
1229
+
1230
+ def primitive_data(self):
1231
+ """
1232
+ Return a primitive version.
1233
+
1234
+ .. SEEALSO::
1235
+
1236
+ :meth:`is_primitive`, :meth:`primitive_index`
1237
+
1238
+ EXAMPLES::
1239
+
1240
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1241
+ sage: H = Hyp(cyclotomic=([3], [4]))
1242
+ sage: H2 = Hyp(gamma_list=[-2, 4, 6, -8])
1243
+ sage: H2.primitive_data() == H
1244
+ True
1245
+ """
1246
+ g = self.gamma_list()
1247
+ d = gcd(g)
1248
+ return HypergeometricData(gamma_list=[x / d for x in g])
1249
+
1250
+ # ----- L-functions -----
1251
+
1252
+ def gauss_table(self, p, f, prec):
1253
+ """
1254
+ Return (and cache) a table of Gauss sums used in the trace formula.
1255
+
1256
+ .. SEEALSO::
1257
+
1258
+ :meth:`gauss_table_full`
1259
+
1260
+ EXAMPLES::
1261
+
1262
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1263
+ sage: H = Hyp(cyclotomic=([3], [4]))
1264
+ sage: H.gauss_table(2, 2, 4)
1265
+ (4, [1 + 2 + 2^2 + 2^3, 1 + 2 + 2^2 + 2^3, 1 + 2 + 2^2 + 2^3])
1266
+ """
1267
+ try:
1268
+ prec1, gtab = self._gauss_table[p, f]
1269
+ if prec1 < prec:
1270
+ raise KeyError
1271
+ except KeyError:
1272
+ use_longs = (p ** prec < 2 ** 31)
1273
+ gtab = gauss_table(p, f, prec, use_longs)
1274
+ self._gauss_table[p, f] = (prec, gtab)
1275
+ prec1 = prec
1276
+ return prec1, gtab
1277
+
1278
+ def gauss_table_full(self):
1279
+ """
1280
+ Return a dict of all stored tables of Gauss sums.
1281
+
1282
+ The result is passed by reference, and is an attribute of the class;
1283
+ consequently, modifying the result has global side effects. Use with
1284
+ caution.
1285
+
1286
+ .. SEEALSO::
1287
+
1288
+ :meth:`gauss_table`
1289
+
1290
+ EXAMPLES::
1291
+
1292
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1293
+ sage: H = Hyp(cyclotomic=([3], [4]))
1294
+ sage: H.euler_factor(2, 7, cache_p=True)
1295
+ 7*T^2 - 3*T + 1
1296
+ sage: H.gauss_table_full()[(7, 1)]
1297
+ (2, array('l', [-1, -29, -25, -48, -47, -22]))
1298
+
1299
+ Clearing cached values::
1300
+
1301
+ sage: H = Hyp(cyclotomic=([3], [4]))
1302
+ sage: H.euler_factor(2, 7, cache_p=True)
1303
+ 7*T^2 - 3*T + 1
1304
+ sage: d = H.gauss_table_full()
1305
+ sage: d.clear() # Delete all entries of this dict
1306
+ sage: H1 = Hyp(cyclotomic=([5], [12]))
1307
+ sage: d1 = H1.gauss_table_full()
1308
+ sage: len(d1.keys()) # No cached values
1309
+ 0
1310
+ """
1311
+ return self._gauss_table
1312
+
1313
+ # --- L-functions ---
1314
+ @cached_method
1315
+ def padic_H_value(self, p, f, t, prec=None, cache_p=False):
1316
+ """
1317
+ Return the `p`-adic trace of Frobenius, computed using the
1318
+ Gross-Koblitz formula.
1319
+
1320
+ If left unspecified, `prec` is set to the minimum `p`-adic precision
1321
+ needed to recover the Euler factor.
1322
+
1323
+ If ``cache_p`` is ``True``, then the function caches an intermediate
1324
+ result which depends only on `p` and `f`. This leads to a significant
1325
+ speedup when iterating over `t`.
1326
+
1327
+ INPUT:
1328
+
1329
+ - ``p`` -- a prime number
1330
+
1331
+ - ``f`` -- integer such that `q = p^f`
1332
+
1333
+ - ``t`` -- a rational parameter
1334
+
1335
+ - ``prec`` -- precision (optional)
1336
+
1337
+ - ``cache_p`` -- boolean
1338
+
1339
+ OUTPUT: integer
1340
+
1341
+ EXAMPLES:
1342
+
1343
+ From Benasque report [Benasque2009]_, page 8::
1344
+
1345
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1346
+ sage: H = Hyp(alpha_beta=([1/2]*4, [0]*4))
1347
+ sage: [H.padic_H_value(3,i,-1) for i in range(1,3)]
1348
+ [0, -12]
1349
+ sage: [H.padic_H_value(5,i,-1) for i in range(1,3)]
1350
+ [-4, 276]
1351
+ sage: [H.padic_H_value(7,i,-1) for i in range(1,3)]
1352
+ [0, -476]
1353
+ sage: [H.padic_H_value(11,i,-1) for i in range(1,3)]
1354
+ [0, -4972]
1355
+
1356
+ From [Roberts2015]_ (but note conventions regarding `t`)::
1357
+
1358
+ sage: H = Hyp(gamma_list=[-6,-1,4,3])
1359
+ sage: t = 189/125
1360
+ sage: H.padic_H_value(13,1,1/t)
1361
+ 0
1362
+
1363
+ TESTS:
1364
+
1365
+ Check issue from :issue:`28404`::
1366
+
1367
+ sage: H1 = Hyp(cyclotomic=([1,1,1], [6,2]))
1368
+ sage: H2 = Hyp(cyclotomic=([6,2], [1,1,1]))
1369
+ sage: [H1.padic_H_value(5,1,i) for i in range(2,5)]
1370
+ [1, -4, -4]
1371
+ sage: [H2.padic_H_value(5,1,i) for i in range(2,5)]
1372
+ [-4, 1, -4]
1373
+
1374
+ Check for potential overflow::
1375
+
1376
+ sage: H = Hyp(cyclotomic=[[10,6], [5,4]])
1377
+ sage: H.padic_H_value(101, 2, 2)
1378
+ -1560629
1379
+
1380
+ Check issue from :issue:`29778`::
1381
+
1382
+ sage: H = Hyp(alpha_beta=([1/5,2/5,3/5,4/5,1/5,2/5,3/5,4/5], [1/4,3/4,1/7,2/7,3/7,4/7,5/7,6/7]))
1383
+ sage: try:
1384
+ ....: print(H.padic_H_value(373, 4, 2))
1385
+ ....: except ValueError as s:
1386
+ ....: print(s)
1387
+ p^f cannot exceed 2^31
1388
+
1389
+ Check error handling for wild and tame primes::
1390
+
1391
+ sage: H = Hyp(alpha_beta=([1/5,2/5,3/5,4/5,1/5,2/5,3/5,4/5], [1/4,3/4,1/7,2/7,3/7,4/7,5/7,6/7]))
1392
+ sage: try:
1393
+ ....: print(H.padic_H_value(5, 1, 2))
1394
+ ....: except NotImplementedError as s:
1395
+ ....: print(s)
1396
+ p is wild
1397
+ sage: try:
1398
+ ....: print(H.padic_H_value(3, 1, 3))
1399
+ ....: except NotImplementedError as s:
1400
+ ....: print(s)
1401
+ p is tame
1402
+
1403
+ Check that :issue:`37910` is resolved::
1404
+
1405
+ sage: H = Hyp(alpha_beta=[[1/2,1/2,1/2,1/2,1/2,1/3,2/3,1/6,5/6], [0,0,0,0,0,0,0,0,0]])
1406
+ sage: H.padic_H_value(151, 2, -512000)
1407
+ 50178940126155881
1408
+
1409
+ REFERENCES:
1410
+
1411
+ - [MagmaHGM]_
1412
+ """
1413
+ alpha = self._alpha
1414
+ beta = self._beta
1415
+ t = QQ(t)
1416
+ if not is_prime(p):
1417
+ raise ValueError('p not prime')
1418
+ if not all(x.denominator() % p for x in self._alpha + self._beta):
1419
+ raise NotImplementedError('p is wild')
1420
+ if t.numerator() % p == 0 or t.denominator() % p == 0:
1421
+ raise NotImplementedError('p is tame')
1422
+
1423
+ if 0 in alpha:
1424
+ return self._swap.padic_H_value(p, f, ~t, prec)
1425
+ q = p ** f
1426
+ if q > 2 ** 31:
1427
+ raise ValueError("p^f cannot exceed 2^31")
1428
+
1429
+ m: dict[int, int] = defaultdict(int)
1430
+ for b in beta:
1431
+ u = b * (q - 1)
1432
+ if u.is_integer():
1433
+ m[u] += 1
1434
+ M = self.M_value()
1435
+ D = -min(self.zigzag(x, flip_beta=True) for x in alpha + beta)
1436
+ # also: D = (self.weight() + 1 - m[0]) // 2
1437
+
1438
+ if prec is None:
1439
+ prec = ceil((self.weight() * f) / 2 + log(2 * self.degree() + 1, p))
1440
+ use_longs = (p ** prec < 2 ** 31)
1441
+
1442
+ gamma = self._gamma_array
1443
+ if cache_p:
1444
+ try:
1445
+ trcoeffs = self._trace_coeffs[p, f]
1446
+ except KeyError:
1447
+ gtab_prec, gtab = self.gauss_table(p, f, prec)
1448
+ trcoeffs = hgm_coeffs(p, f, prec, gamma, m, D, gtab, gtab_prec, use_longs)
1449
+ self._trace_coeffs[p, f] = trcoeffs
1450
+ else:
1451
+ gtab = gauss_table(p, f, prec, use_longs)
1452
+ trcoeffs = hgm_coeffs(p, f, prec, gamma, m, D, gtab, prec, use_longs)
1453
+ sigma = trcoeffs[p - 2]
1454
+ p_ring = sigma.parent()
1455
+
1456
+ teich = p_ring.teichmuller(M / t)
1457
+ for i in range(p - 3, -1, -1):
1458
+ sigma = sigma * teich + trcoeffs[i]
1459
+ resu = ZZ(-1) ** m[0] * sigma / (1 - q)
1460
+ return IntegerModRing(p**prec)(resu).lift_centered()
1461
+
1462
+ trace = padic_H_value
1463
+
1464
+ @cached_method
1465
+ def H_value(self, p, f, t, ring=None):
1466
+ """
1467
+ Return the trace of the Frobenius, computed in terms of Gauss sums
1468
+ using the hypergeometric trace formula.
1469
+
1470
+ INPUT:
1471
+
1472
+ - ``p`` -- a prime number
1473
+
1474
+ - ``f`` -- integer such that `q = p^f`
1475
+
1476
+ - ``t`` -- a rational parameter
1477
+
1478
+ - ``ring`` -- (default: :class:`UniversalCyclotomicfield`)
1479
+
1480
+ The ring could be also ``ComplexField(n)`` or ``QQbar``.
1481
+
1482
+ OUTPUT: integer
1483
+
1484
+ .. WARNING::
1485
+
1486
+ This is apparently working correctly as can be tested
1487
+ using ``ComplexField(70)`` as the value ring.
1488
+
1489
+ Using instead :class:`UniversalCyclotomicfield`, this is much
1490
+ slower than the `p`-adic version :meth:`padic_H_value`.
1491
+
1492
+ Unlike in :meth:`padic_H_value`, tame and wild primes are not supported.
1493
+
1494
+ EXAMPLES:
1495
+
1496
+ With values in the :class:`UniversalCyclotomicField` (slow)::
1497
+
1498
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1499
+
1500
+ sage: # needs sage.libs.gap sage.rings.number_field
1501
+ sage: H = Hyp(alpha_beta=([1/2]*4, [0]*4))
1502
+ sage: [H.H_value(3,i,-1) for i in range(1,3)]
1503
+ [0, -12]
1504
+ sage: [H.H_value(5,i,-1) for i in range(1,3)]
1505
+ [-4, 276]
1506
+ sage: [H.H_value(7,i,-1) for i in range(1,3)] # not tested
1507
+ [0, -476]
1508
+ sage: [H.H_value(11,i,-1) for i in range(1,3)] # not tested
1509
+ [0, -4972]
1510
+ sage: [H.H_value(13,i,-1) for i in range(1,3)] # not tested
1511
+ [-84, -1420]
1512
+
1513
+ With values in :class:`ComplexField`::
1514
+
1515
+ sage: [H.H_value(5,i,-1, ComplexField(60)) for i in range(1,3)] # needs sage.libs.gap sage.rings.number_field
1516
+ [-4, 276]
1517
+
1518
+ Check issue from :issue:`28404`::
1519
+
1520
+ sage: H1 = Hyp(cyclotomic=([1,1,1], [6,2]))
1521
+ sage: H2 = Hyp(cyclotomic=([6,2], [1,1,1]))
1522
+ sage: [H1.H_value(5,1,i) for i in range(2,5)]
1523
+ [1, -4, -4]
1524
+ sage: [H2.H_value(5,1,QQ(i)) for i in range(2,5)]
1525
+ [-4, 1, -4]
1526
+
1527
+ TESTS:
1528
+
1529
+ Check issue from :issue:`29778`::
1530
+
1531
+ sage: H = Hyp(cyclotomic=[[5,5], [4,7]])
1532
+ sage: try:
1533
+ ....: print(H.padic_H_value(373, 4, 2))
1534
+ ....: except ValueError as s:
1535
+ ....: print(s)
1536
+ p^f cannot exceed 2^31
1537
+
1538
+ Check error handling for wild and tame primes::
1539
+
1540
+ sage: H = Hyp(cyclotomic=[[5,5], [4,7]])
1541
+ sage: try:
1542
+ ....: print(H.padic_H_value(5, 1, 2))
1543
+ ....: except NotImplementedError as s:
1544
+ ....: print(s)
1545
+ p is wild
1546
+ sage: try:
1547
+ ....: print(H.padic_H_value(3, 1, 3))
1548
+ ....: except NotImplementedError as s:
1549
+ ....: print(s)
1550
+ p is tame
1551
+
1552
+ REFERENCES:
1553
+
1554
+ - [BeCoMe]_ (Theorem 1.3)
1555
+ - [Benasque2009]_
1556
+ """
1557
+ alpha = self._alpha
1558
+ beta = self._beta
1559
+ t = QQ(t)
1560
+ if not is_prime(p):
1561
+ raise ValueError('p not prime')
1562
+ if not all(x.denominator() % p for x in self._alpha + self._beta):
1563
+ raise NotImplementedError('p is wild')
1564
+ if (t.numerator() * t.denominator() % p == 0 or (t - 1) % p == 0):
1565
+ raise NotImplementedError('p is tame')
1566
+
1567
+ if 0 in alpha:
1568
+ return self._swap.H_value(p, f, ~t, ring)
1569
+ if ring is None:
1570
+ ring = UniversalCyclotomicField()
1571
+ gamma = self.gamma_array()
1572
+ q = p**f
1573
+
1574
+ m = {r: beta.count(QQ((r, q - 1))) for r in range(q - 1)}
1575
+ D = -min(self.zigzag(x, flip_beta=True) for x in alpha + beta)
1576
+ # also: D = (self.weight() + 1 - m[0]) // 2
1577
+ M = self.M_value()
1578
+
1579
+ Fq = GF((p, f))
1580
+ gen = Fq.multiplicative_generator()
1581
+ zeta_q = ring.zeta(q - 1)
1582
+
1583
+ tM = Fq(M / t)
1584
+ for k in range(q - 1):
1585
+ if gen ** k == tM:
1586
+ teich = zeta_q ** k
1587
+ break
1588
+
1589
+ gauss_table = [gauss_sum(zeta_q ** r, Fq) for r in range(q - 1)]
1590
+
1591
+ sigma = sum(q**(D + m[0] - m[r]) *
1592
+ prod(gauss_table[(-v * r) % (q - 1)]**gv
1593
+ for v, gv in gamma.items()) *
1594
+ teich ** r
1595
+ for r in range(q - 1))
1596
+ resu = ZZ(-1) ** m[0] / (1 - q) * sigma
1597
+ if not ring.is_exact():
1598
+ resu = resu.real_part().round()
1599
+ return resu
1600
+
1601
+ def sign(self, t, p):
1602
+ """
1603
+ Return the sign of the functional equation for the Euler factor of the motive `H_t` at the prime `p`.
1604
+
1605
+ For odd weight, the sign of the functional equation is +1. For even
1606
+ weight, the sign is computed by a recipe found in Section 11.1 of [Watkins]_
1607
+ (when 0 is not in alpha).
1608
+
1609
+ EXAMPLES::
1610
+
1611
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1612
+ sage: H = Hyp(cyclotomic=([6,2], [1,1,1]))
1613
+ sage: H.weight(), H.degree()
1614
+ (2, 3)
1615
+ sage: [H.sign(1/4,p) for p in [5,7,11,13,17,19]]
1616
+ [1, 1, -1, -1, 1, 1]
1617
+
1618
+ sage: H = Hyp(alpha_beta=([1/12,5/12,7/12,11/12], [0,1/2,1/2,1/2]))
1619
+ sage: H.weight(), H.degree()
1620
+ (2, 4)
1621
+ sage: t = -5
1622
+ sage: [H.sign(1/t,p) for p in [11,13,17,19,23,29]]
1623
+ [-1, -1, -1, 1, 1, 1]
1624
+
1625
+ We check that :issue:`28404` is fixed::
1626
+
1627
+ sage: H = Hyp(cyclotomic=([1,1,1], [6,2]))
1628
+ sage: [H.sign(4,p) for p in [5,7,11,13,17,19]]
1629
+ [1, 1, -1, -1, 1, 1]
1630
+ """
1631
+ t = QQ(t)
1632
+ if 0 in self._alpha:
1633
+ return self._swap.sign(~t, p)
1634
+ d = self.degree()
1635
+ w = self.weight()
1636
+
1637
+ if w % 2: # sign is always +1 for odd weight
1638
+ sign = 1
1639
+ elif d % 2:
1640
+ sign = -kronecker_symbol((1 - t) * self._sign_param, p)
1641
+ else:
1642
+ sign = kronecker_symbol(t * (t - 1) * self._sign_param, p)
1643
+ return sign
1644
+
1645
+ def euler_factor_tame_contribution(self, t, p, mo, deg=None):
1646
+ """
1647
+ Return a contribution to the Euler factor of the motive `H_t` at a tame prime.
1648
+
1649
+ The output is only nontrivial when `t` has nonzero `p`-adic valuation.
1650
+ The algorithm is described in Section 11.4.1 of [Watkins]_.
1651
+
1652
+ INPUT:
1653
+
1654
+ - ``t`` -- rational number, not 0 or 1
1655
+
1656
+ - ``p`` -- prime number of good reduction
1657
+
1658
+ - ``mo`` -- integer
1659
+
1660
+ - ``deg`` -- integer (optional)
1661
+
1662
+ OUTPUT: a polynomial
1663
+
1664
+ If ``deg`` is specified, the output is truncated to that degree (inclusive).
1665
+
1666
+ EXAMPLES::
1667
+
1668
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1669
+ sage: H = Hyp(cyclotomic=[[3,7], [4,5,6]])
1670
+ sage: H.euler_factor_tame_contribution(11^2, 11, 4)
1671
+ 1
1672
+ sage: H.euler_factor_tame_contribution(11^20, 11, 4)
1673
+ 1331*T^2 + 1
1674
+ sage: H.euler_factor_tame_contribution(11^20, 11, 4, deg=1)
1675
+ 1
1676
+ sage: H.euler_factor_tame_contribution(11^20, 11, 5)
1677
+ 1771561*T^4 + 161051*T^3 + 6171*T^2 + 121*T + 1
1678
+ sage: H.euler_factor_tame_contribution(11^20, 11, 5, deg=3)
1679
+ 161051*T^3 + 6171*T^2 + 121*T + 1
1680
+ sage: H.euler_factor_tame_contribution(11^20, 11, 6)
1681
+ 1
1682
+ """
1683
+ t = QQ(t)
1684
+ if t in [0, 1]:
1685
+ raise ValueError('invalid t')
1686
+ if not is_prime(p):
1687
+ raise ValueError('p not prime')
1688
+ if not all(x.denominator() % p for x in self._alpha + self._beta):
1689
+ raise NotImplementedError('p is wild')
1690
+
1691
+ e = t.valuation(p)
1692
+ t0 = t / p**e
1693
+ if e > 0:
1694
+ mul = self.cyclotomic_data()[1].count(mo)
1695
+ elif e < 0:
1696
+ mul = self.cyclotomic_data()[0].count(mo)
1697
+ else:
1698
+ mul = None
1699
+ if e % mo or not mul:
1700
+ return ZZ.one()
1701
+ d = euler_phi(mo)
1702
+ f = IntegerModRing(mo)(p).multiplicative_order()
1703
+ if deg is None:
1704
+ deg = d
1705
+ if deg < f:
1706
+ return ZZ.one()
1707
+ q = p ** f
1708
+ prec = ceil(deg*(self.weight()+1-mul)/2 + log(2*d + 1, p))
1709
+ k = (q-1) // mo
1710
+ flip = (f == 1 and prec == 1)
1711
+ gtab_prec, gtab = self.gauss_table(p, f, prec)
1712
+ try:
1713
+ p_ring = gtab[0].parent()
1714
+ except AttributeError:
1715
+ p_ring = Zp(p, prec, 'fixed-mod')
1716
+ M = self.M_value()
1717
+ teich = p_ring.teichmuller(M / t0)
1718
+ m = {r: self._beta.count(QQ((r, q - 1))) for r in range(q - 1)}
1719
+ D = -min(self.zigzag(x, flip_beta=True) for x in self._alpha + self._beta)
1720
+ gamma = self.gamma_array()
1721
+ l = []
1722
+ for j in range(mo):
1723
+ if gcd(j, mo) == 1:
1724
+ r = j * k
1725
+ term = teich**r * ZZ(-1)**m[0]
1726
+ ct = 0
1727
+ for v, gv in gamma.items():
1728
+ r1 = v * r % (q-1)
1729
+ ct += gv * sum(r1.digits(p))
1730
+ term *= p_ring(gtab[r1]) ** (-gv if flip else gv)
1731
+ ct //= p - 1
1732
+ term *= ZZ(-1) ** ct
1733
+ ct += f * (D + m[0] - m[r])
1734
+ l.append(term * p**ct)
1735
+ traces = [0 if j % f else sum(i ** (j//f) for i in l) for j in range(1,d+1)]
1736
+ R = IntegerModRing(p**prec)
1737
+ traces = [R(i).lift_centered() for i in traces]
1738
+ return characteristic_polynomial_from_traces(traces, d, p, 0, 1, deg, use_fe=False)
1739
+
1740
+ @cached_method
1741
+ def euler_factor(self, t, p, deg=None, cache_p=False):
1742
+ """
1743
+ Return the Euler factor of the motive `H_t` at prime `p`.
1744
+
1745
+ INPUT:
1746
+
1747
+ - ``t`` -- rational number, not 0
1748
+
1749
+ - ``p`` -- prime number of good reduction
1750
+
1751
+ - ``deg`` -- integer or ``None``
1752
+
1753
+ OUTPUT: a polynomial
1754
+
1755
+ See [Benasque2009]_ for explicit examples of Euler factors.
1756
+
1757
+ For odd weight, the sign of the functional equation is +1. For even
1758
+ weight, the sign is computed by a recipe found in Section 11.1 of [Watkins]_.
1759
+
1760
+ If ``deg`` is specified, then the polynomial is only computed up to degree
1761
+ ``deg`` (inclusive).
1762
+
1763
+ The prime `p` may be tame, but not wild. When `v_p(t-1)` is nonzero and even,
1764
+ the Euler factor includes a linear term described in Section 11.2 of [Watkins]_.
1765
+
1766
+ EXAMPLES::
1767
+
1768
+ sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
1769
+ sage: H = Hyp(alpha_beta=([1/2]*4, [0]*4))
1770
+ sage: H.euler_factor(-1, 5)
1771
+ 15625*T^4 + 500*T^3 - 130*T^2 + 4*T + 1
1772
+
1773
+ sage: H = Hyp(gamma_list=[-6,-1,4,3])
1774
+ sage: H.weight(), H.degree()
1775
+ (1, 2)
1776
+ sage: t = 189/125
1777
+ sage: [H.euler_factor(1/t,p) for p in [11,13,17,19,23,29]]
1778
+ [11*T^2 + 4*T + 1,
1779
+ 13*T^2 + 1,
1780
+ 17*T^2 + 1,
1781
+ 19*T^2 + 1,
1782
+ 23*T^2 + 8*T + 1,
1783
+ 29*T^2 + 2*T + 1]
1784
+
1785
+ sage: H = Hyp(cyclotomic=([6,2], [1,1,1]))
1786
+ sage: H.weight(), H.degree()
1787
+ (2, 3)
1788
+ sage: [H.euler_factor(1/4,p) for p in [5,7,11,13,17,19]]
1789
+ [125*T^3 + 20*T^2 + 4*T + 1,
1790
+ 343*T^3 - 42*T^2 - 6*T + 1,
1791
+ -1331*T^3 - 22*T^2 + 2*T + 1,
1792
+ -2197*T^3 - 156*T^2 + 12*T + 1,
1793
+ 4913*T^3 + 323*T^2 + 19*T + 1,
1794
+ 6859*T^3 - 57*T^2 - 3*T + 1]
1795
+
1796
+ sage: H = Hyp(alpha_beta=([1/12,5/12,7/12,11/12], [0,1/2,1/2,1/2]))
1797
+ sage: H.weight(), H.degree()
1798
+ (2, 4)
1799
+ sage: t = -5
1800
+ sage: [H.euler_factor(1/t,p) for p in [11,13,17,19,23,29]]
1801
+ [-14641*T^4 - 1210*T^3 + 10*T + 1,
1802
+ -28561*T^4 - 2704*T^3 + 16*T + 1,
1803
+ -83521*T^4 - 4046*T^3 + 14*T + 1,
1804
+ 130321*T^4 + 14440*T^3 + 969*T^2 + 40*T + 1,
1805
+ 279841*T^4 - 25392*T^3 + 1242*T^2 - 48*T + 1,
1806
+ 707281*T^4 - 7569*T^3 + 696*T^2 - 9*T + 1]
1807
+
1808
+ This is an example of higher degree::
1809
+
1810
+ sage: H = Hyp(cyclotomic=([11], [7, 12]))
1811
+ sage: H.euler_factor(2, 13)
1812
+ 371293*T^10 - 85683*T^9 + 26364*T^8 + 1352*T^7 - 65*T^6 + 394*T^5 - 5*T^4 + 8*T^3 + 12*T^2 - 3*T + 1
1813
+ sage: H.euler_factor(2, 13, deg=4)
1814
+ -5*T^4 + 8*T^3 + 12*T^2 - 3*T + 1
1815
+ sage: H.euler_factor(2, 19) # long time
1816
+ 2476099*T^10 - 651605*T^9 + 233206*T^8 - 77254*T^7 + 20349*T^6 - 4611*T^5 + 1071*T^4 - 214*T^3 + 34*T^2 - 5*T + 1
1817
+
1818
+ This is an example of tame primes::
1819
+
1820
+ sage: H = Hyp(cyclotomic=[[4,2,2], [3,1,1]])
1821
+ sage: H.euler_factor(8, 7)
1822
+ -7*T^3 + 7*T^2 - T + 1
1823
+ sage: H.euler_factor(50, 7)
1824
+ -7*T^3 + 7*T^2 - T + 1
1825
+ sage: H.euler_factor(7, 7)
1826
+ -T + 1
1827
+ sage: H.euler_factor(1/7^2, 7)
1828
+ T + 1
1829
+ sage: H.euler_factor(1/7^4, 7)
1830
+ 7*T^3 + 7*T^2 + T + 1
1831
+
1832
+ This is an example with `t = 1`::
1833
+
1834
+ sage: H = Hyp(cyclotomic=[[4,2], [3,1]])
1835
+ sage: H.euler_factor(1, 7)
1836
+ -T^2 + 1
1837
+ sage: H = Hyp(cyclotomic=[[5], [1,1,1,1]])
1838
+ sage: H.euler_factor(1, 7)
1839
+ 343*T^2 - 6*T + 1
1840
+
1841
+ TESTS::
1842
+
1843
+ sage: H1 = Hyp(alpha_beta=([1,1,1], [1/2,1/2,1/2]))
1844
+ sage: H2 = H1.swap_alpha_beta()
1845
+ sage: H1.euler_factor(-1, 3)
1846
+ 27*T^3 + 3*T^2 + T + 1
1847
+ sage: H2.euler_factor(-1, 3)
1848
+ 27*T^3 + 3*T^2 + T + 1
1849
+ sage: H = Hyp(alpha_beta=([0,0,0,1/3,2/3], [1/2,1/5,2/5,3/5,4/5]))
1850
+ sage: H.euler_factor(5,7)
1851
+ 16807*T^5 - 686*T^4 - 105*T^3 - 15*T^2 - 2*T + 1
1852
+
1853
+ Check for precision downsampling::
1854
+
1855
+ sage: H = Hyp(cyclotomic=[[3], [4]])
1856
+ sage: H.euler_factor(2, 11, cache_p=True)
1857
+ 11*T^2 - 3*T + 1
1858
+ sage: H = Hyp(cyclotomic=[[12], [1,2,6]])
1859
+ sage: H.euler_factor(2, 11, cache_p=True)
1860
+ -T^4 + T^3 - T + 1
1861
+
1862
+ Check issue from :issue:`29778`::
1863
+
1864
+ sage: H = Hyp(cyclotomic=[[5,5], [4,7]])
1865
+ sage: try:
1866
+ ....: print(H.euler_factor(2, 373))
1867
+ ....: except ValueError as s:
1868
+ ....: print(s)
1869
+ p^f cannot exceed 2^31
1870
+
1871
+ Check handling of some tame cases::
1872
+
1873
+ sage: H = Hyp(cyclotomic=[[4,2,2,2], [3,1,1,1]])
1874
+ sage: H.euler_factor(8, 7)
1875
+ 2401*T^4 - 392*T^3 + 46*T^2 - 8*T + 1
1876
+ sage: H.euler_factor(50, 7)
1877
+ 16807*T^5 - 343*T^4 - 70*T^3 - 10*T^2 - T + 1
1878
+ sage: H = Hyp(cyclotomic=[[3,7], [4,5,6]])
1879
+ sage: H.euler_factor(11, 11)
1880
+ 1
1881
+ sage: H.euler_factor(11**4, 11)
1882
+ 1331*T^2 + 1
1883
+ sage: H.euler_factor(11**5, 11)
1884
+ 1771561*T^4 + 161051*T^3 + 6171*T^2 + 121*T + 1
1885
+ sage: H.euler_factor(11**5, 11, deg=3)
1886
+ 161051*T^3 + 6171*T^2 + 121*T + 1
1887
+ sage: H.euler_factor(11**-3, 11)
1888
+ 1331*T^2 + 1
1889
+ sage: H.euler_factor(11**-7, 11)
1890
+ 2357947691*T^6 - 58564*T^3 + 1
1891
+ sage: H = Hyp(cyclotomic=[[7], [5,1,1]])
1892
+ sage: H.euler_factor(2, 2)
1893
+ -T + 1
1894
+ sage: H.euler_factor(2^-7, 2)
1895
+ 8*T^6 - 2*T^3 + 1
1896
+ sage: H.euler_factor(3, 2)
1897
+ 4*T^5 + 4*T^4 + 2*T^3 + 2*T^2 + T + 1
1898
+
1899
+ More examples of tame primes from [Watkins]_::
1900
+
1901
+ sage: H = Hyp(cyclotomic=[[3,12], [6,6,1,1]])
1902
+ sage: H.euler_factor(1/8, 7).factor()
1903
+ (-1) * (7*T - 1) * (117649*T^4 + 2744*T^3 + 105*T^2 + 8*T + 1)
1904
+ sage: H.euler_factor(1/12, 11).factor()
1905
+ (11*T + 1) * (1771561*T^4 - 18634*T^3 + 22*T^2 - 14*T + 1)
1906
+ sage: H = Hyp(cyclotomic=[[4,4,4],[6,2,1,1,1]])
1907
+ sage: H.euler_factor(1/8, 7).factor()
1908
+ (49*T + 1) * (5764801*T^4 - 86436*T^3 + 2758*T^2 - 36*T + 1)
1909
+ sage: H.euler_factor(1/12, 11).factor()
1910
+ (-1) * (121*T - 1) * (214358881*T^4 - 527076*T^3 + 12694*T^2 - 36*T + 1)
1911
+ sage: H = Hyp(cyclotomic=[[10,4,2], [18,1]])
1912
+ sage: H.euler_factor(1/14, 13)
1913
+ -4826809*T^6 + 114244*T^5 + 2197*T^4 - 13*T^2 - 4*T + 1
1914
+
1915
+ Check error handling for wild primes::
1916
+
1917
+ sage: H = Hyp(cyclotomic=[[5,5], [4,7]])
1918
+ sage: try:
1919
+ ....: print(H.euler_factor(2, 5))
1920
+ ....: except NotImplementedError as s:
1921
+ ....: print(s)
1922
+ p is wild
1923
+
1924
+ REFERENCES:
1925
+
1926
+ - [Roberts2015]_
1927
+ - [Watkins]_
1928
+ """
1929
+ t = QQ(t)
1930
+ if t == 0:
1931
+ raise ValueError('invalid t')
1932
+ if not is_prime(p):
1933
+ raise ValueError('p not prime')
1934
+ if not all(x.denominator() % p for x in self._alpha + self._beta):
1935
+ raise NotImplementedError('p is wild')
1936
+ if 0 in self._alpha:
1937
+ return self._swap.euler_factor(~t, p)
1938
+ P = PolynomialRing(ZZ, 'T')
1939
+ if t.numerator() % p == 0 or t.denominator() % p == 0:
1940
+ ans = P.one()
1941
+ for m in {j for i in self.cyclotomic_data() for j in i}:
1942
+ ans *= self.euler_factor_tame_contribution(t, p, m, deg)
1943
+ if deg is not None:
1944
+ ans = ans.truncate(deg + 1)
1945
+ return ans
1946
+ # now p is good, or p is tame and t is a p-adic unit
1947
+ elif (t - 1) % p == 0:
1948
+ typ = "mult"
1949
+ d = self.degree() - 1
1950
+ if d % 2:
1951
+ d -= 1
1952
+ else:
1953
+ typ = "good"
1954
+ d = self.degree()
1955
+ bound = d // 2
1956
+ if deg is not None:
1957
+ bound = min(deg, bound)
1958
+
1959
+ if p ** bound > 2 ** 31:
1960
+ raise ValueError("p^f cannot exceed 2^31")
1961
+
1962
+ traces = [self.padic_H_value(p, i + 1, t, cache_p=cache_p)
1963
+ for i in range(bound)]
1964
+
1965
+ w = self.weight()
1966
+ m1 = self.cyclotomic_data()[1].count(1)
1967
+
1968
+ # In the multiplicative case, we sometimes need to pull out a linear factor
1969
+ # in order to apply the functional equation.
1970
+ if typ == "mult":
1971
+ if self.degree() % 2 == 0:
1972
+ sign = 1
1973
+ if w % 2:
1974
+ assert m1 % 2 == 0
1975
+ u = (-1) ** (m1//2)
1976
+ u *= prod(v ** gv for v, gv in self.gamma_array().items())
1977
+ c = kronecker_symbol(u, p) * p**((w-1)//2)
1978
+ else:
1979
+ u = (-1) ** (1 + self.degree()//2 + (m1-1)//2)
1980
+ num, den = self.defining_polynomials()
1981
+ x = num.parent().gen()
1982
+ num = num(-x)
1983
+ num /= (x-1) ** num.valuation(x-1)
1984
+ den /= (x-1) ** den.valuation(x-1)
1985
+ u *= 2 * num(1) / den(1)
1986
+ c = kronecker_symbol(u, p) * p**(w//2)
1987
+ cpow = c
1988
+ for j in range(len(traces)):
1989
+ traces[j] -= cpow
1990
+ cpow *= c
1991
+ tmp = 1 - c*P.gen()
1992
+ else:
1993
+ u = (-1) ** (1+(self.degree()-1)//2)
1994
+ num, den = self.defining_polynomials()
1995
+ x = num.parent().gen()
1996
+ den = den(-x)
1997
+ num /= (x-1) ** num.valuation(x-1)
1998
+ den /= (x-1) ** den.valuation(x-1)
1999
+ u *= num(1) / den(1)
2000
+ sign = kronecker_symbol(u, p)
2001
+ else:
2002
+ sign = self.sign(t, p)
2003
+
2004
+ ans = characteristic_polynomial_from_traces(traces, d, p, w, sign, deg=deg)
2005
+
2006
+ # In the multiplicative case, we sometimes need to add extra factors.
2007
+ if typ == "mult" and t != 1:
2008
+ if self.degree() % 2 == 0:
2009
+ ans *= tmp
2010
+ if w % 2 == 0 and (t-1).valuation(p) % 2 == 0:
2011
+ K = (-1) ** ((m1-1)//2)*2*prod(abs(x) for x in self.gamma_list())
2012
+ t0 = (~t-1) / p**((t-1).valuation(p))
2013
+ c = kronecker_symbol(K*t0, p) * p**(w//2)
2014
+ ans *= 1 - c*P.gen()
2015
+ if deg is not None:
2016
+ ans = ans.truncate(deg + 1)
2017
+ return ans