Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Goss polynomials of Drinfeld modules #35991

Merged
merged 10 commits into from
Aug 27, 2023
7 changes: 5 additions & 2 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2661,6 +2661,9 @@ REFERENCES:
TR-737-05, (2005).
ftp://ftp.cs.princeton.edu/reports/2005/737.pdf

.. [Gek1988] \E.-U. Gekeler, On the coefficients of Drinfel'd modular
forms. Invent. Math. 93 (1988), no. 3, 667-700

.. [Gek1991] \E.-U. Gekeler. On finite Drinfeld modules. Journal of
algebra, 1(141):187–203, 1991.

Expand Down Expand Up @@ -2724,9 +2727,9 @@ REFERENCES:
doubles of finite groups*. PhD Thesis,
University of California, Santa Cruz. 1999.

.. [GoMa2010] Christopher Goff and Geoffrey Mason,
.. [GoMa2010] Christopher Goff and Geoffrey Mason,
*Generalized twisted quantum doubles and the McKay correspondence*,
J. Algebra 324 (2010), no. 11, 3007–3016.
J. Algebra 324 (2010), no. 11, 3007–3016.

.. [GJ2016] Muddappa Seetharama Gowda and Juyoung Jeong.
Spectral cones in Euclidean Jordan algebras.
Expand Down
86 changes: 86 additions & 0 deletions src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,92 @@ def gen(self):
"""
return self._gen

@cached_method
def _compute_goss_polynomial(self, n, q, poly_ring, X):
r"""
Utility function for computing the n-th Goss polynomial.

The user should not call this method directly, but
:meth:`goss_polynomial` instead.

TESTS::

sage: A = GF(2^2)['T']
sage: K.<T> = Frac(A)
sage: phi = DrinfeldModule(A, [T, T+1, T^2, 1])
sage: poly_ring = phi.base()['X']
sage: X = poly_ring.gen()
sage: phi._compute_goss_polynomial(0, 2^2, poly_ring, X)
0
sage: phi._compute_goss_polynomial(3, 2^2, poly_ring, X)
X^3
sage: phi._compute_goss_polynomial(4*3, 2^2, poly_ring, X)
X^12
sage: phi._compute_goss_polynomial(9, 2^2, poly_ring, X)
X^9 + (1/(T^3 + T^2 + T))*X^6 + (1/(T^6 + T^4 + T^2))*X^3

"""
# Trivial cases
if n.is_zero():
return poly_ring.zero()
if n <= q - 1:
return X**n
if n%q == 0:
return self.goss_polynomial(ZZ(n/q))**q
# General case
pol = sum(self._compute_coefficient_exp(i+1)
*self._compute_goss_polynomial(n - q**(i+1), q, poly_ring, X)
for i in range(0, (n.log(q).n()).floor()))
return X*(self._compute_goss_polynomial(n - 1, q, poly_ring, X) + pol)

def goss_polynomial(self, n, var='X'):
r"""
Return the `n`-th Goss polynomial of the Drinfeld module.

Note that Goss polynomials are only defined for Drinfeld modules
of characteristic zero.

INPUT:

- ``n`` (integer) -- the index of the Goss polynomial

- ``var`` (str, default: ``'X'``) -- the name of polynomial
variable.

OUTPUT:

- a univariate polynomial in ``var`` over the base `A`-field.

EXAMPLES::

sage: A = GF(3)['T']
sage: K.<T> = Frac(A)
sage: phi = DrinfeldModule(A, [T, 1]) # Carlitz module
sage: phi.goss_polynomial(1)
X
sage: phi.goss_polynomial(2)
X^2
sage: phi.goss_polynomial(4)
X^4 + (1/(T^3 + 2*T))*X^2
sage: phi.goss_polynomial(5)
X^5 + (2/(T^3 + 2*T))*X^3
sage: phi.goss_polynomial(10)
X^10 + (1/(T^3 + 2*T))*X^8 + (1/(T^6 + T^4 + T^2))*X^6 + (1/(T^9 + 2*T^3))*X^4 + (1/(T^18 + 2*T^12 + 2*T^10 + T^4))*X^2

REFERENCE:

Section 3 of [Gek1988]_ provides an exposition of Goss
polynomials.
"""
if self.category()._characteristic:
raise ValueError(f"characteristic must be zero (={self.characteristic()})")
n = ZZ(n)
K = self.base()
poly_ring = K[var]
X = poly_ring.gen()
q = self._Fq.cardinality()
return self._compute_goss_polynomial(n, q, poly_ring, X)

def height(self):
r"""
Return the height of the Drinfeld module if the function field
Expand Down