Graded rings of Drinfeld modular forms¶
This module defines a class named DrinfeldModularForms.
Currently, the implementation only supports the full modular group
\(\mathrm{GL}_r(A)\) where \(A = \mathbb{F}_q[T]\).
The implementation is based on the following identification:
where \(g_i\) is the \(i\)-th coefficient form of weight \(q^{i} - 1\).
AUTHORS:
- David Ayotte (2022): initial version 
- class sage.modular.drinfeld_modform.ring.DrinfeldModularForms(base_ring, rank, group, has_type, names)[source]¶
- Bases: - Parent,- UniqueRepresentation- Base class for the graded ring of Drinfeld modular forms. - If \(K = \mathrm{Frac}(A)\) where \(A = \mathbb{F}_q[T]\), then the ring of Drinfeld modular forms over \(K\) of rank \(r\) and type zero for \(\mathrm{GL}_r(A)\) is \[M^{r, 0}(\mathrm{GL}_r(A)) = K[g_1, \ldots, g_{r-1}, g_{r}].\]- where \(g_i\) the \(i\)-th coefficient form of weight \(q^{i} - 1\) at \(T\). - Similarly, the ring of Drinfeld modular forms over \(K\) of rank \(r\) and arbitrary type is \[M^{r}(\mathrm{GL}_r(A)) = K[g_1, \ldots, g_{r-1}, h_{r}].\]- where \(h_r\) is a form of weight \((q^r - 1)/(q - 1)\) and type \(1\). - We will see the elements of this ring as formal objects given by algebraic combination of the generator of the ring. See the class - DrinfeldModularFormsElementfor more details about their implementation.- INPUT: - base_ring– the fraction field of a univariate polynomial ring over \(\mathbb{F}_q\)
- rankinteger (default:- None); the rank of the ring. If the rank is- None, then the names of the generators must be specified.
- group– (not implemented, default:- None) the group of the ring. The current implementation only supports the full modular group \(\mathrm{GL}_r(A)\).
- has_type– boolean (default:- False); if set to- True, returns the graded ring of arbitrary type
- names– string, tuple or list (default:- None); a single character, a tuple or list of character, or comma separated string of character representing the names of the generators. If this parameter is set to- Noneand the rank is specified, then the default names for the generators will be:- g1, g2, ..., grfor the type zero forms
- g1, g2, ..., hrfor the arbitrary type forms.
 - If this parameter is a single character, for example - f, and a rank is specified, then the names will be of the form- f1, f2, ..., fr. Finally, if this parameter is a list, a tupe or a string of comma separated characters, then each character will corresponds to a generator. Note that in this case, it not necessary to specify the rank.
 - EXAMPLES: - sage: q = 3 sage: A = GF(q)['T'] sage: K.<T> = Frac(A) sage: M = DrinfeldModularForms(K, 3) sage: M Ring of Drinfeld modular forms of rank 3 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3 - >>> from sage.all import * >>> q = Integer(3) >>> A = GF(q)['T'] >>> K = Frac(A, names=('T',)); (T,) = K._first_ngens(1) >>> M = DrinfeldModularForms(K, Integer(3)) >>> M Ring of Drinfeld modular forms of rank 3 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3 - Use the - gens()method to obtain the generators of the ring:- sage: M.gens() (g1, g2, g3) sage: M.inject_variables() # assign the variable g1, g2, g3 Defining g1, g2, g3 sage: T*g1*g2 + g3 g3 + T*g1*g2 - >>> from sage.all import * >>> M.gens() (g1, g2, g3) >>> M.inject_variables() # assign the variable g1, g2, g3 Defining g1, g2, g3 >>> T*g1*g2 + g3 g3 + T*g1*g2 - When creating the ring, one can name the generators in various ways: - sage: M.<F, G, H> = DrinfeldModularForms(K) sage: M.gens() (F, G, H) sage: M = DrinfeldModularForms(K, 5, names='f') # must specify the rank sage: M.gens() (f1, f2, f3, f4, f5) sage: M = DrinfeldModularForms(K, names='u, v, w, x') sage: M.gens() (u, v, w, x) sage: M = DrinfeldModularForms(K, names=['F', 'G', 'H']) sage: M.gens() (F, G, H) - >>> from sage.all import * >>> M = DrinfeldModularForms(K, names=('F', 'G', 'H',)); (F, G, H,) = M._first_ngens(3) >>> M.gens() (F, G, H) >>> M = DrinfeldModularForms(K, Integer(5), names='f') # must specify the rank >>> M.gens() (f1, f2, f3, f4, f5) >>> M = DrinfeldModularForms(K, names='u, v, w, x') >>> M.gens() (u, v, w, x) >>> M = DrinfeldModularForms(K, names=['F', 'G', 'H']) >>> M.gens() (F, G, H) - Set the keyword parameter - has_typeto- Truein order to create the ring of Drinfeld modular forms of arbitrary type:- sage: M = DrinfeldModularForms(K, 4, has_type=True) sage: M.gens() (g1, g2, g3, h4) sage: h4 = M.3 sage: h4.type() 1 - >>> from sage.all import * >>> M = DrinfeldModularForms(K, Integer(4), has_type=True) >>> M.gens() (g1, g2, g3, h4) >>> h4 = M.gen(3) >>> h4.type() 1 - To obtain a generating set of the subspace of forms of a fixed weight, use the methode - basis_of_weight():- sage: M = DrinfeldModularForms(K, 2) sage: M.basis_of_weight(q^3 - 1) [g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13] - >>> from sage.all import * >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.basis_of_weight(q**Integer(3) - Integer(1)) [g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13] - In order to compute the coefficient forms, use the methods - coefficient_form()and- coefficient_forms():- sage: M = DrinfeldModularForms(K, 3) sage: M.coefficient_form(1) g1 sage: M.coefficient_form(2) g2 sage: M.coefficient_form(3) g3 sage: M.coefficient_forms(T) [g1, g2, g3] sage: M.coefficient_forms(T^2) [(T^3 + T)*g1, g1^4 + (T^9 + T)*g2, g1^9*g2 + g1*g2^3 + (T^27 + T)*g3, g1^27*g3 + g1*g3^3 + g2^10, g2^27*g3 + g2*g3^9, g3^28] - >>> from sage.all import * >>> M = DrinfeldModularForms(K, Integer(3)) >>> M.coefficient_form(Integer(1)) g1 >>> M.coefficient_form(Integer(2)) g2 >>> M.coefficient_form(Integer(3)) g3 >>> M.coefficient_forms(T) [g1, g2, g3] >>> M.coefficient_forms(T**Integer(2)) [(T^3 + T)*g1, g1^4 + (T^9 + T)*g2, g1^9*g2 + g1*g2^3 + (T^27 + T)*g3, g1^27*g3 + g1*g3^3 + g2^10, g2^27*g3 + g2*g3^9, g3^28] - REFERENCE: - For a quick introduction to Drinfeld modular forms, see the tutorial. For more extensive references, see [Gek1988] and [BRP2018]. - Element[source]¶
- alias of - DrinfeldModularFormsElement
 - basis(k)[source]¶
- Return a list of Drinfeld modular forms which forms a basis for the subspace of weight \(k\). - Note that if \(k\not\equiv 0\) modulo \(q-1\), then the subspace is 0. - An alias of this method is - basis.- INPUT: - k– integer
 - EXAMPLES: - sage: q = 3; A = GF(q)['T']; K = Frac(A); sage: M = DrinfeldModularForms(K, 2) sage: M.basis_of_weight(q - 1) [g1] sage: M.basis_of_weight(q^2 - 1) [g2, g1^4] sage: M.basis_of_weight(q^3 - 1) [g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13] sage: M.basis_of_weight(19*(q-1)) [g1^3*g2^4, g1^7*g2^3, g1^11*g2^2, g1^15*g2, g1^19] - >>> from sage.all import * >>> q = Integer(3); A = GF(q)['T']; K = Frac(A); >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.basis_of_weight(q - Integer(1)) [g1] >>> M.basis_of_weight(q**Integer(2) - Integer(1)) [g2, g1^4] >>> M.basis_of_weight(q**Integer(3) - Integer(1)) [g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13] >>> M.basis_of_weight(Integer(19)*(q-Integer(1))) [g1^3*g2^4, g1^7*g2^3, g1^11*g2^2, g1^15*g2, g1^19] 
 - basis_of_weight(k)[source]¶
- Return a list of Drinfeld modular forms which forms a basis for the subspace of weight \(k\). - Note that if \(k\not\equiv 0\) modulo \(q-1\), then the subspace is 0. - An alias of this method is - basis.- INPUT: - k– integer
 - EXAMPLES: - sage: q = 3; A = GF(q)['T']; K = Frac(A); sage: M = DrinfeldModularForms(K, 2) sage: M.basis_of_weight(q - 1) [g1] sage: M.basis_of_weight(q^2 - 1) [g2, g1^4] sage: M.basis_of_weight(q^3 - 1) [g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13] sage: M.basis_of_weight(19*(q-1)) [g1^3*g2^4, g1^7*g2^3, g1^11*g2^2, g1^15*g2, g1^19] - >>> from sage.all import * >>> q = Integer(3); A = GF(q)['T']; K = Frac(A); >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.basis_of_weight(q - Integer(1)) [g1] >>> M.basis_of_weight(q**Integer(2) - Integer(1)) [g2, g1^4] >>> M.basis_of_weight(q**Integer(3) - Integer(1)) [g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13] >>> M.basis_of_weight(Integer(19)*(q-Integer(1))) [g1^3*g2^4, g1^7*g2^3, g1^11*g2^2, g1^15*g2, g1^19] 
 - coefficient_form(i, a=None)[source]¶
- Return the \(i\)-th coefficient form of the universal Drinfeld module over \(\Omega^r(\mathbb{C}_{\infty})\): \[\phi_{w, a} = a + g_{1, a}\tau + \cdots + g_{r d_a, a}\tau^{r d_a}\]- where \(d_a := \mathrm{deg}(a)\). - INPUT: - i– integer between 1 and \(r d_a\)
- a– (default:- None) an element in the ring of regular functions. If \(a\) is- None, then the method returns the \(i\)-th coefficient form of \(\phi_{w, T}\).
 - EXAMPLES: - sage: q = 3 sage: A = GF(q)['T'] sage: K.<T> = Frac(A) sage: M = DrinfeldModularForms(K, 3) sage: M.coefficient_form(1) g1 sage: M.coefficient_form(2) g2 sage: M.coefficient_form(3) g3 sage: M.coefficient_form(3, T^2) g1^9*g2 + g1*g2^3 + (T^27 + T)*g3 - >>> from sage.all import * >>> q = Integer(3) >>> A = GF(q)['T'] >>> K = Frac(A, names=('T',)); (T,) = K._first_ngens(1) >>> M = DrinfeldModularForms(K, Integer(3)) >>> M.coefficient_form(Integer(1)) g1 >>> M.coefficient_form(Integer(2)) g2 >>> M.coefficient_form(Integer(3)) g3 >>> M.coefficient_form(Integer(3), T**Integer(2)) g1^9*g2 + g1*g2^3 + (T^27 + T)*g3 - sage: M = DrinfeldModularForms(K, 2, has_type=True) sage: M.coefficient_form(1) g1 sage: M.coefficient_form(2) h2^2 sage: M.coefficient_form(2, T^3 + T^2 + T) (T^9 + T^3 + T + 1)*g1^4 + (T^18 + T^10 + T^9 + T^2 + T + 1)*h2^2 - >>> from sage.all import * >>> M = DrinfeldModularForms(K, Integer(2), has_type=True) >>> M.coefficient_form(Integer(1)) g1 >>> M.coefficient_form(Integer(2)) h2^2 >>> M.coefficient_form(Integer(2), T**Integer(3) + T**Integer(2) + T) (T^9 + T^3 + T + 1)*g1^4 + (T^18 + T^10 + T^9 + T^2 + T + 1)*h2^2 
 - coefficient_forms(a=None)[source]¶
- Return the list of all coefficients of the universal Drinfeld module at \(a\). - See also - coefficient_form()for definitions.- INPUT: - a– (default:- None) an element in the ring of regular functions. If \(a\) is- None, then the method returns the coefficients forms at \(a = T\).
 - OUTPUT: list of Drinfeld modular forms. The \(i\)-th element of that list corresponds to the \((i+1)\)-th coefficient form at \(a\). - EXAMPLES: - sage: q = 3 sage: A = GF(q)['T'] sage: K.<T> = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: M.coefficient_forms() [g1, g2] sage: M.coefficient_forms(T^2) [(T^3 + T)*g1, g1^4 + (T^9 + T)*g2, g1^9*g2 + g1*g2^3, g2^10] sage: M.coefficient_forms(T^3) [(T^6 + T^4 + T^2)*g1, (T^9 + T^3 + T)*g1^4 + (T^18 + T^10 + T^2)*g2, g1^13 + (T^27 + T^9 + T)*g1^9*g2 + (T^27 + T^3 + T)*g1*g2^3, g1^36*g2 + g1^28*g2^3 + g1^4*g2^9 + (T^81 + T^9 + T)*g2^10, g1^81*g2^10 + g1^9*g2^28 + g1*g2^30, g2^91] - >>> from sage.all import * >>> q = Integer(3) >>> A = GF(q)['T'] >>> K = Frac(A, names=('T',)); (T,) = K._first_ngens(1) >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.coefficient_forms() [g1, g2] >>> M.coefficient_forms(T**Integer(2)) [(T^3 + T)*g1, g1^4 + (T^9 + T)*g2, g1^9*g2 + g1*g2^3, g2^10] >>> M.coefficient_forms(T**Integer(3)) [(T^6 + T^4 + T^2)*g1, (T^9 + T^3 + T)*g1^4 + (T^18 + T^10 + T^2)*g2, g1^13 + (T^27 + T^9 + T)*g1^9*g2 + (T^27 + T^3 + T)*g1*g2^3, g1^36*g2 + g1^28*g2^3 + g1^4*g2^9 + (T^81 + T^9 + T)*g2^10, g1^81*g2^10 + g1^9*g2^28 + g1*g2^30, g2^91] 
 - gen(n)[source]¶
- Return the \(n\)-th generator of this ring. - EXAMPLES: - sage: A = GF(3)['T']; K = Frac(A); T = K.gen() sage: M = DrinfeldModularForms(K, 2) sage: M.gen(0) g1 sage: M.1 # equivalent to M.gen(1) g2 - >>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A); T = K.gen() >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.gen(Integer(0)) g1 >>> M.gen(1) # equivalent to M.gen(1) g2 - Note - Recall that the ring of Drinfeld modular forms is generated by the \(r\) coefficient forms of the universal Drinfeld module at \(T\), \(g_1, g_2, \ldots, g_r\), see - coefficient_forms(). We highlight however that we make a shift in the indexing so that the \(i\)-th generator corresponds to the \(i+1\)-th coefficient form for \(0\leq i \leq r-1\).
 - gens()[source]¶
- Return a tuple of generators of this ring. - EXAMPLES: - sage: A = GF(3)['T']; K = Frac(A); T = K.gen() sage: M = DrinfeldModularForms(K, 5) sage: M.gens() (g1, g2, g3, g4, g5) - >>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A); T = K.gen() >>> M = DrinfeldModularForms(K, Integer(5)) >>> M.gens() (g1, g2, g3, g4, g5) 
 - ngens()[source]¶
- Return the number of generators of this ring. - Note that the number of generators is equal to the rank. - EXAMPLES: - sage: A = GF(3)['T']; K = Frac(A); T = K.gen() sage: M = DrinfeldModularForms(K, 5) sage: M.ngens() 5 - >>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A); T = K.gen() >>> M = DrinfeldModularForms(K, Integer(5)) >>> M.ngens() 5 
 - one()[source]¶
- Return the multiplicative unit. - EXAMPLES: - sage: A = GF(3)['T']; K = Frac(A); T = K.gen() sage: M = DrinfeldModularForms(K, 2) sage: M.one() 1 sage: M.one() * M.0 g1 sage: M.one().is_one() True - >>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A); T = K.gen() >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.one() 1 >>> M.one() * M.gen(0) g1 >>> M.one().is_one() True 
 - polynomial_ring()[source]¶
- Return the multivariate polynomial ring over the base ring where each variable corresponds to a generator of this Drinfeld modular forms ring. - EXAMPLES: - sage: q = 3; A = GF(q)['T']; K = Frac(A); sage: M = DrinfeldModularForms(K, 2) sage: P = M.polynomial_ring() sage: P Multivariate Polynomial Ring in g1, g2 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3 - >>> from sage.all import * >>> q = Integer(3); A = GF(q)['T']; K = Frac(A); >>> M = DrinfeldModularForms(K, Integer(2)) >>> P = M.polynomial_ring() >>> P Multivariate Polynomial Ring in g1, g2 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3 - The degree of the variables corresponds to the weight of the associated generator: - sage: P.inject_variables() Defining g1, g2 sage: g1.degree() 2 sage: g2.degree() 8 - >>> from sage.all import * >>> P.inject_variables() Defining g1, g2 >>> g1.degree() 2 >>> g2.degree() 8 
 - rank()[source]¶
- Return the rank of this ring of Drinfeld modular forms. - EXAMPLES: - sage: A = GF(3)['T']; K = Frac(A); sage: DrinfeldModularForms(K, 2).rank() 2 sage: DrinfeldModularForms(K, 3).rank() 3 sage: DrinfeldModularForms(K, 4).rank() 4 - >>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A); >>> DrinfeldModularForms(K, Integer(2)).rank() 2 >>> DrinfeldModularForms(K, Integer(3)).rank() 3 >>> DrinfeldModularForms(K, Integer(4)).rank() 4 
 - zero()[source]¶
- Return the additive identity. - EXAMPLES: - sage: A = GF(3)['T']; K = Frac(A); T = K.gen() sage: M = DrinfeldModularForms(K, 2) sage: M.zero() 0 sage: M.zero() + M.1 g2 sage: M.zero() * M.1 0 sage: M.zero().is_zero() True - >>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A); T = K.gen() >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.zero() 0 >>> M.zero() + M.gen(1) g2 >>> M.zero() * M.gen(1) 0 >>> M.zero().is_zero() True