Expansion at infinity for rank 2#

In analogy with the classical theory, any Drinfeld modular form \(f:\Omega^2(\mathbb{C}_{\infty}) \rightarrow \mathbb{C}_{\infty}\) admits an expansion at infinity of the form:

\[f(w) = \sum_{i = 0}^{\infty} a_i(f) u(w)^i\]

where \(u(w) := 1/e(w)\) and \(e(w)\) is the exponential of the Carlitz module \(T\mapsto T + \tau\).

We say that a Drinfeld modular forms of weight \(k\) admits an \(A\)-expansion if there exists an integer \(n\) and coefficients \(c_{a}(f)\) such that

\[\begin{split}f = \sum_{\substack{a\in \mathbb{F}_q[T] \\ a\text{ monic}}} c_a(f)G_n(u(az))\end{split}\]

where \(G_n(X)\) is the \(n\)-th Goss polynomial of the Carlitz module.

Petrov showed that there exists an infinite family of Drinfeld modular forms with \(A\)-expansion:

\[\begin{split}f_{k, n} = \sum_{\substack{a\in \mathbb{F}_q[T] \\ a\text{ monic}}} a^{k - n}G_n(u(az))\end{split}\]

provided that \(k\) and \(n\) are integers such that \(k - 2n \equiv 0\) modulo \(q - 1\) and \(n \leq p^{v_p(k - n)}\). The set of all forms \(f_{k, n}\) will be called the Petrov family.

This module defines functions that compute the expansion at infinity of any \(A\)-expansion.

EXAMPLES:

sage: from drinfeld_modular_forms import compute_petrov_expansion
sage: q = 3
sage: D = compute_petrov_expansion(q + 1, 1, q); D
u + u^5 + ((2*T^3+T)*u^7) + O(u^8)

It is possible to compute on demands any coefficients of the above series:

sage: D[59]  # 59-th coefficient
2*T^27 + T^9 + T^3 + 2*T
sage: D[0:10]  # first 10 coefficients
[0, 1, 0, 0, 0, 1, 0, 2*T^3 + T, 0, 1]

AUTHORS:

  • David Ayotte (2021): initial version

drinfeld_modular_forms.expansions.coefficient_A_expansion(coeff_stream, n, i, param)#

Return the \(i\)-th coefficient of a general \(A\)-expansion.

INPUT:

  • coeff_stream (function) – corresponds to the function \(a\mapsto c_a\) where \(c_a\) is the \(a\)-th coefficient of the \(A\)-expansion;

  • \(n\) (integer) – the exponent of the \(A\)-expansion;

  • i – an integer representing the index of the coefficient to compute;

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

EXAMPLE:

sage: from drinfeld_modular_forms import coefficient_A_expansion
sage: coeff_stream = lambda a: a^2 - 1
sage: coefficient_A_expansion(coeff_stream, 10, 6, 3)
2/(T^18 + 2*T^12 + 2*T^10 + T^4)
sage: coeff_stream = lambda a: a^3
sage: coefficient_A_expansion(coeff_stream, 1, 7, 3)
2*T^3 + T
drinfeld_modular_forms.expansions.coefficient_petrov_expansion(k, n, i, param)#

Return the \(i\)-th coefficient of the expansion for the form \(f_{k, n}\).

INPUT:

  • k – an integer representing the weight of the resulting form.

  • n – an integer. The type of the resulting form will be congruent to this integer modulo \(q-1\).

  • i – an integer representing the index of the coefficient to compute.

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

EXAMPLES:

sage: from drinfeld_modular_forms import coefficient_petrov_expansion
sage: q = 3
sage: coefficient_petrov_expansion(q + 1, 1, 1, q)
1
sage: coefficient_petrov_expansion(q + 1, 1, 0, q)
0
sage: coefficient_petrov_expansion(q + 1, 1, 1, q)
1
sage: coefficient_petrov_expansion(q + 1, 1, 7, q)
2*T^3 + T
drinfeld_modular_forms.expansions.compute_A_expansion(coeff_stream, n, param, name='u')#

Return the general \(A\)-expansion defined by

\[\begin{split}c_0 + \sum_{\substack{a\in \mathbb{F}_q[T] \\ a\text{ monic}}} c_a G_n(u(az))\end{split}\]

as a lazy power series.

Note that the returned power series might not always represent a Drinfeld modular form.

INPUT:

  • coeff_stream (function) – corresponds to the function \(a\mapsto c_a\) where \(c_a\) is the \(a\)-th coefficient of the \(A\)-expansion;

  • \(n\) (integer) – the exponent of the \(A\)-expansion;

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring;

  • name (string, default: 'u') – represent the parameter at infinity.

EXAMPLE:

sage: from drinfeld_modular_forms import compute_A_expansion
sage: c_h = lambda a: a^3
sage: compute_A_expansion(c_h, 1, 3)
u + u^5 + O(u^7)
sage: c_Delta = lambda a: a^6
sage: D = compute_A_expansion(c_Delta, 2, 3); D
u^2 + 2*u^6 + O(u^7)
sage: D[38]
T^18 + 2*T^12 + 2*T^10 + T^4 + 1
sage: c = lambda a: a^5 - a + 2
sage: compute_A_expansion(c, 8, 5)
2 + ((1/(T^5+4*T))*u^4) + O(u^7)
drinfeld_modular_forms.expansions.compute_delta_rank_2(param, name='u')#

Return the expansion of the normalized Drinfeld modular discriminant of rank 2.

Recall that for \(w\in \Omega^2(\mathbb{C}_{\infty})\) the Drinfeld modular discriminant is the leading coefficient of the Drinfeld module

\[\phi_{w} : T \mapsto T + g(z)\tau + \Delta(w)\tau^2\]

corresponding to the lattice \(\Lambda_w := wA + A\). The normalized discriminant is the form \(\Delta_0(w)\) such that its first nonzero coefficient is 1.

INPUT:

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

  • name (string, default: 'u') – represent the parameter at infinity.

OUTPUT: a lazy power series over the base ring.

Note

We have \(\Delta_0(w) = f_{q^2 - 1, q - 1}\).

EXAMPLES:

sage: from drinfeld_modular_forms import compute_delta_rank_2
sage: q = 3
sage: D = compute_delta_rank_2(q); D
u^2 + 2*u^6 + O(u^8)
sage: D[38]
T^18 + 2*T^12 + 2*T^10 + T^4 + 1
sage: D[56]
2*T^27 + 2*T^3 + 2*T
drinfeld_modular_forms.expansions.compute_eisentein_series_rank_2(param, name='u')#

Return the expansion fo the normalized Drinfeld Eisenstein series of weight \(q-1\).

Recall that this form is defined by:

\[E_{q-1}(w) := \frac{T^q - T}{\tilde{\pi}^{q-1}} \sum_{(c, d)\in A^2\setminus 0} \frac{1}{(cw + d)^{q-1}}.\]

where \(\tilde{\pi}\) is the Carlitz period.

INPUT:

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

  • name (string, default: 'u') – represent the parameter at infinity.

OUTPUT: a lazy power series over the base ring.

Note

We have \(E_{q-1} = 1 - (T^q - T)f_{q - 1, q - 1}\).

EXAMPLES:

sage: from drinfeld_modular_forms import compute_eisentein_series_rank_2
sage: q = 3
sage: E = compute_eisentein_series_rank_2(q); E
1 + ((2*T^3+T)*u^2) + O(u^7)
sage: E[0:15]
[1, 0, 2*T^3 + T, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2*T^3 + T]
drinfeld_modular_forms.expansions.compute_h_rank_2(param, name='u')#

Return the expansion of the function \(h\) defined by \(\Delta = h^{q-1}\) and having an expansion of the form \(u + O(u^2)\).

INPUT:

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

  • name (string, default: 'u') – represent the parameter at infinity.

EXAMPLES:

sage: from drinfeld_modular_forms import compute_h_rank_2
sage: q = 3
sage: h = compute_h_rank_2(q); h
u + u^5 + ((2*T^3+T)*u^7) + O(u^8)
sage: h[0:15]
[0, 1, 0, 0, 0, 1, 0, 2*T^3 + T, 0, 1, 0, T^3 + 2*T, 0, T^6 + T^4 + T^2 + 1, 0]
drinfeld_modular_forms.expansions.compute_petrov_expansion(k, n, param, name='u', check=True)#

Return the \(A\)-expansion of the form \(f_{k, n}\) as a lazy power series.

Recall that it is defined by:

\[\begin{split}f_{k, n} = \sum_{\substack{a\in \mathbb{F}_q[T] \\ a\text{ monic}}} a^{k - n}G_n(u(az))\end{split}\]

INPUT:

  • k – an integer equal to the weight of the resulting form.

  • n – an integer congruent to the type modulo \(q-1\).

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

  • name (string, default: 'u') – represent the parameter at infinity.

  • check (Boolean, default: True) – If this parameter is set to True, the code will check if \(k\) and \(n\) verify the three conditions:

    • \(k - 2n > 0\);

    • \(q - 1\) divides \(k - 2n\);

    • \(n > p^{v_p(k - n)}\).

OUTPUT: A lazy power series.

EXAMPLES:

sage: from drinfeld_modular_forms import compute_petrov_expansion
sage: q = 3
sage: D = compute_petrov_expansion(q + 1, 1, q); D
u + u^5 + ((2*T^3+T)*u^7) + O(u^8)

To obtain more coefficient, one just need to take slices the series:

sage: D[0:10]  # output the coefficients from i=0...9
[0, 1, 0, 0, 0, 1, 0, 2*T^3 + T, 0, 1]
sage: D[39]  # print the 39-th coefficient
T^9 + 2*T^3
sage: D[59]  # 59-th coefficient
2*T^27 + T^9 + T^3 + 2*T
drinfeld_modular_forms.expansions.inverse_cyclotomic_polynomial(a, name='X')#

Return the polynomial \(f_a(X) = \rho_a(X^{-1}) X^{q^{\mathrm{deg}(a)}}\) where \(\rho_a\) is the Carlitz module.

This function is used in parameter_at_infinity()

INPUT:

  • a (polynomial) – univariate polynomial over a finite field.

  • name (string, default: 'X') – the name of the variable.

EXAMPLES:

sage: from drinfeld_modular_forms.expansions import inverse_cyclotomic_polynomial
sage: A.<T> = GF(3)['T']
sage: inverse_cyclotomic_polynomial(A.one())
1
sage: inverse_cyclotomic_polynomial(T)
T*X^2 + 1
sage: inverse_cyclotomic_polynomial(T^2)
T^2*X^8 + (T^3 + T)*X^6 + 1
sage: inverse_cyclotomic_polynomial(T^2 + T + 1)
(T^2 + T + 1)*X^8 + (T^3 + T + 1)*X^6 + 1
drinfeld_modular_forms.expansions.j_invariant(param, name='u')#

Return the \(j\)-invariant defined by \(j := g_1^{q+1}/g_2\).

It is normalized so that \(j = 1/u^{q - 1} + O(1)\).

INPUT:

  • param – a prime power, a univariate polynomial ring over \(\mathbb{F}_q\) or the fraction field of such polynomial ring.

  • name (string, default: 'u') – represent the parameter at infinity.

EXAMPLES:

sage: from drinfeld_modular_forms import j_invariant
sage: q = 3
sage: j_invariant(q)
1/u^2 + (2*T^3+T) + u^2 + ((2*T^9+2*T^3+2*T)*u^4) + O(u^5)
sage: q = 4
sage: j_invariant(q)
1/u^3 + (T^4+T) + O(u^4)
drinfeld_modular_forms.expansions.parameter_at_infinity(a, name='u')#

Return the function \(u(aw)\) as a power series in \(u\).

INPUT:

  • a (polynomial) – univariate polynomial over a finite field.

  • name (string, default: 'u') – the name of the lazy power series ring generator.

EXAMPLES:

sage: from drinfeld_modular_forms import parameter_at_infinity
sage: A.<T> = GF(3)['T']
sage: parameter_at_infinity(A.one())
u
sage: parameter_at_infinity(T)
u^3 + 2*T*u^5 + T^2*u^7 + 2*T^3*u^9 + O(u^10)
sage: parameter_at_infinity(T^2)
u^9 + ((2*T^3+2*T)*u^15) + O(u^16)