Skip to content

Commit 7332a53

Browse files
author
Release Manager
committed
gh-37187: implement E_polynomial of hypergeometric motive This is adding a new method tp hypergeometric motives. ### 📝 Checklist - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation accordingly. URL: #37187 Reported by: Frédéric Chapoton Reviewer(s):
2 parents 5a561ab + 076f323 commit 7332a53

File tree

1 file changed

+77
-2
lines changed

1 file changed

+77
-2
lines changed

src/sage/modular/hypergeometric_motive.py

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
from sage.combinat.integer_vector_weighted import WeightedIntegerVectors
6666
from sage.functions.generalized import sgn
6767
from sage.functions.log import log
68-
from sage.functions.other import floor, ceil
68+
from sage.functions.other import floor, ceil, frac
6969
from sage.misc.cachefunc import cached_method
7070
from sage.misc.functional import cyclotomic_polynomial
7171
from sage.misc.misc_c import prod
@@ -74,14 +74,15 @@
7474
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
7575
from sage.rings.integer_ring import ZZ
7676
from sage.rings.padics.padic_generic_element import gauss_table
77-
from sage.rings.polynomial.polynomial_ring import polygen
77+
from sage.rings.polynomial.polynomial_ring import polygen, polygens
7878
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
7979
from sage.rings.power_series_ring import PowerSeriesRing
8080
from sage.rings.rational_field import QQ
8181
from sage.schemes.generic.spec import Spec
8282
from sage.rings.finite_rings.finite_field_constructor import GF
8383
from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField
8484

85+
8586
def characteristic_polynomial_from_traces(traces, d, q, i, sign):
8687
r"""
8788
Given a sequence of traces `t_1, \dots, t_k`, return the
@@ -899,6 +900,80 @@ def hodge_polygon_vertices(self):
899900
lst.append((lst[-1][0] + hn[i], lst[-1][1] + i * hn[i]))
900901
return lst
901902

903+
def E_polynomial(self, vars=None):
904+
"""
905+
Return the E-polynomial of ``self``.
906+
907+
This is a bivariate polynomial.
908+
909+
The algorithm is taken from [FRV2019]_.
910+
911+
INPUT:
912+
913+
- ``vars`` -- optional pair of variables (default `u,v`)
914+
915+
REFERENCES:
916+
917+
.. [FRV2019] Fernando Rodriguez Villegas, *Mixed Hodge numbers
918+
and factorial ratios*, :arxiv:`1907.02722`
919+
920+
EXAMPLES::
921+
922+
sage: from sage.modular.hypergeometric_motive import HypergeometricData
923+
sage: H = HypergeometricData(gamma_list=[-30,-1,6,10,15])
924+
sage: H.E_polynomial()
925+
8*u*v + 7*u + 7*v + 8
926+
927+
sage: p, q = polygens(QQ,'p,q')
928+
sage: H.E_polynomial((p, q))
929+
8*p*q + 7*p + 7*q + 8
930+
931+
sage: H = HypergeometricData(gamma_list=(-11, -2, 1, 3, 4, 5))
932+
sage: H.E_polynomial()
933+
5*u^2*v + 5*u*v^2 + u*v + 1
934+
935+
sage: H = HypergeometricData(gamma_list=(-63, -8, -2, 1, 4, 16, 21, 31))
936+
sage: H.E_polynomial()
937+
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
938+
"""
939+
gamma = self.gamma_list()
940+
ell = len(gamma)
941+
942+
gamma_plus = [g for g in gamma if g > 0]
943+
gamma_minus = [g for g in gamma if g < 0]
944+
945+
domain = set(d for g in gamma for d in divisors(g.abs()))
946+
947+
m_plus = {d: len([1 for g in gamma_plus if not g % d])
948+
for d in domain}
949+
950+
m_minus = {d: len([1 for g in gamma_minus if not g % d])
951+
for d in domain}
952+
953+
if vars is None:
954+
u, v = polygens(ZZ, 'u,v')
955+
else:
956+
u, v = vars
957+
uqv = u / v
958+
uv = u * v
959+
960+
A = u.parent()
961+
delta_sharp_N = {d: A.sum(uqv**sum(frac(j * gi / d) for gi in gamma)
962+
for j in d.coprime_integers(d))
963+
for d in domain}
964+
965+
loop = [(d, m_plus[d], m_minus[d]) for d in domain]
966+
967+
delta_sharp = sum((uqv**m - uqv**p) // (uqv - 1) * v**(ell - 1)
968+
* delta_sharp_N[d]
969+
for d, p, m in loop if m > p)
970+
971+
delta_zero = sum((uv**min(m, p) - 1) // (uv - 1) * v**(ell - m - p)
972+
* delta_sharp_N[d]
973+
for d, p, m in loop)
974+
975+
return (delta_sharp + delta_zero - 1).numerator() // (u * v)
976+
902977
def M_value(self):
903978
"""
904979
Return the `M` coefficient that appears in the trace formula.

0 commit comments

Comments
 (0)