Skip to content

Commit fac8c54

Browse files
author
Xavier Caruso
committed
optimize dwork_relation
1 parent 3c0d91f commit fac8c54

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

src/sage/functions/hypergeometric_algebraic.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class HypergeometricAlgebraic(Element):
7878
r"""
7979
Class for hypergeometric functions over arbitrary base rings.
8080
"""
81-
def __init__(self, parent, arg1, arg2=None, scalar=None):
81+
def __init__(self, parent, arg1, arg2=None, scalar=None, check=True):
8282
r"""
8383
Initialize this hypergeometric function.
8484
@@ -119,7 +119,7 @@ def __init__(self, parent, arg1, arg2=None, scalar=None):
119119
else:
120120
parameters = HypergeometricParameters(arg1, arg2)
121121
char = self.parent()._char
122-
if scalar:
122+
if check and scalar:
123123
if any(b in ZZ and b <= 0 for b in parameters.bottom):
124124
raise ValueError("the parameters %s do not define a hypergeometric function" % parameters)
125125
if char > 0:
@@ -1072,7 +1072,7 @@ def is_maximum_unipotent_monodromy(self):
10721072
# Over the p-adics
10731073

10741074
class HypergeometricAlgebraic_padic(HypergeometricAlgebraic):
1075-
def __init__(self, parent, arg1, arg2=None, scalar=None):
1075+
def __init__(self, parent, arg1, arg2=None, scalar=None, check=True):
10761076
r"""
10771077
Initialize this hypergeometric function.
10781078
@@ -1103,7 +1103,7 @@ def __init__(self, parent, arg1, arg2=None, scalar=None):
11031103
<class 'sage.functions.hypergeometric_algebraic.HypergeometricFunctions.element_class'>
11041104
sage: TestSuite(h).run()
11051105
"""
1106-
HypergeometricAlgebraic.__init__(self, parent, arg1, arg2, scalar)
1106+
HypergeometricAlgebraic.__init__(self, parent, arg1, arg2, scalar, check)
11071107
K = self.base_ring()
11081108
self._p = K.prime()
11091109
self._e = K.e()
@@ -1312,8 +1312,8 @@ def __call__(self, x):
13121312
# Over prime finite fields
13131313

13141314
class HypergeometricAlgebraic_GFp(HypergeometricAlgebraic):
1315-
def __init__(self, parent, arg1, arg2=None, scalar=None):
1316-
HypergeometricAlgebraic.__init__(self, parent, arg1, arg2, scalar)
1315+
def __init__(self, parent, arg1, arg2=None, scalar=None, check=True):
1316+
HypergeometricAlgebraic.__init__(self, parent, arg1, arg2, scalar, check)
13171317
self._p = p = self.base_ring().cardinality()
13181318
self._coeffs = [Qp(p, 1)(self._scalar)]
13191319

@@ -1380,29 +1380,42 @@ def dwork_relation(self):
13801380
Return (P1, h1), ..., (Ps, hs) such that
13811381
13821382
self = P1*h1^p + ... + Ps*hs^p
1383+
1384+
TESTS::
1385+
1386+
sage: S.<x> = GF(3)[]
1387+
sage: f = hypergeometric([7/8, 9/8, 11/8], [3/2, 7/4], x)
1388+
sage: f.dwork_relation()
1389+
{hypergeometric((3/8, 5/8, 9/8), (1/2, 5/4), x): 1,
1390+
hypergeometric((1, 21/8, 25/8, 27/8), (3, 13/4, 7/2), x): 2*x^7}
13831391
"""
13841392
parameters = self._parameters
13851393
if not parameters.is_balanced():
13861394
raise ValueError("the hypergeometric function must be a pFq with q = p-1")
13871395
p = self._char
13881396
H = self.parent()
13891397
F = H.base_ring()
1390-
x = H.polynomial_ring().gen()
1398+
S = H.polynomial_ring()
13911399
coeffs = self._coeffs
1400+
pas = parameters.top + parameters.bottom
1401+
criticals = [(1-pa) % p for pa in pas]
1402+
criticals.sort()
1403+
criticals.append(p)
13921404
Ps = {}
1393-
for r in range(p):
1394-
params = parameters.shift(r).dwork_image(p)
1405+
for i in range(len(pas))
1406+
ci = criticals[i]
1407+
cj = criticals[i+1]
1408+
if cj == ci:
1409+
continue
1410+
params = parameters.shift(ci).dwork_image(p)
13951411
_, s, _ = params.valuation_position(p)
1396-
h = H(params.shift(s))
1397-
e = s*p + r
1398-
if e >= len(coeffs):
1399-
self._compute_coeffs(e + 1)
1400-
c = F(coeffs[e])
1401-
if c:
1402-
if h in Ps:
1403-
Ps[h] += c * x**e
1404-
else:
1405-
Ps[h] = c * x**e
1412+
ci += s*p
1413+
cj += s*p
1414+
h = H(params.shift(s), check=False)
1415+
self._compute_coeffs(cj + 1)
1416+
P = S(self._coeffs[ci:cj])
1417+
if P:
1418+
Ps[h] = Ps.get(h, 0) + (P << ci)
14061419
return Ps
14071420

14081421
def annihilating_ore_polynomial(self, var='Frob'):

0 commit comments

Comments
 (0)