Elements of Drinfeld modular forms rings¶
This module defines the elements of the class
DrinfeldModularForms
.
AUTHORS:
David Ayotte (2022): initial version
- class sage.modular.drinfeld_modform.element.DrinfeldModularFormsElement(parent, polynomial)[source]¶
Bases:
ModuleElement
Element class of rings of Drinfeld modular forms.
Recall that a graded Drinfeld form is a sum of Drinfeld modular forms having potentially different weights:
\[F = f_{k_1} + f_{k_2} + \cdots + f_{k_n}\]where \(f_{k_i}\) is a Drinfeld modular form of weight \(k_i\). We also say that \(f_{k_i}\) is an homogeneous component of weight \(k_i\). If \(n=1\), then we say that \(F\) is homogeneous of weight \(k_1\).
EXAMPLES: use the
inject_variable
method of the parent to quickly assign variables names to the generators:sage: A = GF(3)['T'] sage: K.<T> = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: M.inject_variables() Defining g1, g2 sage: g1 in M True sage: g2.parent() Ring of Drinfeld modular forms of rank 2 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3
>>> from sage.all import * >>> A = GF(Integer(3))['T'] >>> K = Frac(A, names=('T',)); (T,) = K._first_ngens(1) >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.inject_variables() Defining g1, g2 >>> g1 in M True >>> g2.parent() Ring of Drinfeld modular forms of rank 2 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3
A = GF(3)['T'] K.<T> = Frac(A) M = DrinfeldModularForms(K, 2) M.inject_variables() g1 in M g2.parent()
Next, via algebraic combination of the generator, we may create any element of the ring:
sage: F = g1*g2 + g2 sage: F g1*g2 + g2 sage: F.is_homogeneous() False sage: F.homogeneous_components() {8: g2, 10: g1*g2}
>>> from sage.all import * >>> F = g1*g2 + g2 >>> F g1*g2 + g2 >>> F.is_homogeneous() False >>> F.homogeneous_components() {8: g2, 10: g1*g2}
F = g1*g2 + g2 F F.is_homogeneous() F.homogeneous_components()
If the created form is homogeneous, we can ask for its weight in which case it will be a Drinfeld modular form:
sage: H = g1^4*g2^9 + T*g1^8*g2^8 + (T^2 - 1)*g1^28*g2^3 sage: H.is_homogeneous() True sage: H.weight() 80
>>> from sage.all import * >>> H = g1**Integer(4)*g2**Integer(9) + T*g1**Integer(8)*g2**Integer(8) + (T**Integer(2) - Integer(1))*g1**Integer(28)*g2**Integer(3) >>> H.is_homogeneous() True >>> H.weight() 80
H = g1^4*g2^9 + T*g1^8*g2^8 + (T^2 - 1)*g1^28*g2^3 H.is_homogeneous() H.weight()
You can also construct an element by simply passing a multivariate polynomial to the parent:
sage: f1, f2 = polygens(K, 2, 'f1, f2') sage: M(f1) g1 sage: M(f2) g2 sage: M(T*f1 + f2^3 + T^2 + 1) g2^3 + T*g1 + (T^2 + 1)
>>> from sage.all import * >>> f1, f2 = polygens(K, Integer(2), 'f1, f2') >>> M(f1) g1 >>> M(f2) g2 >>> M(T*f1 + f2**Integer(3) + T**Integer(2) + Integer(1)) g2^3 + T*g1 + (T^2 + 1)
f1, f2 = polygens(K, 2, 'f1, f2') M(f1) M(f2) M(T*f1 + f2^3 + T^2 + 1)
Note
This class should not be directly instanciated, instead create an instance of the parent
DrinfeldModularForms
and access its elements using the relevant methods.- homogeneous_components()[source]¶
Return the homogeneous components of this graded Drinfeld form.
EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: M.inject_variables() Defining g1, g2 sage: F = g1 + g1^2 + g1*g2^2 + g2^4 sage: D = F.homogeneous_components(); D {2: g1, 4: g1^2, 18: g1*g2^2, 32: g2^4} sage: D[32] g2^4
>>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.inject_variables() Defining g1, g2 >>> F = g1 + g1**Integer(2) + g1*g2**Integer(2) + g2**Integer(4) >>> D = F.homogeneous_components(); D {2: g1, 4: g1^2, 18: g1*g2^2, 32: g2^4} >>> D[Integer(32)] g2^4
A = GF(3)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2) M.inject_variables() F = g1 + g1^2 + g1*g2^2 + g2^4 D = F.homogeneous_components(); D D[32]
- is_homogeneous()[source]¶
Return whether the graded form is homogeneous in the weight.
We recall that elements of Drinfeld modular forms ring are not necessarily modular forms as they may have mixed weight components.
EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: M.inject_variables() Defining g1, g2 sage: f = g1^5*g2^2 # homogeneous polynomial sage: f.is_homogeneous() True sage: g = g1 + g2 # mixed weight components sage: g.is_homogeneous() False
>>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.inject_variables() Defining g1, g2 >>> f = g1**Integer(5)*g2**Integer(2) # homogeneous polynomial >>> f.is_homogeneous() True >>> g = g1 + g2 # mixed weight components >>> g.is_homogeneous() False
A = GF(3)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2) M.inject_variables() f = g1^5*g2^2 # homogeneous polynomial f.is_homogeneous() g = g1 + g2 # mixed weight components g.is_homogeneous()
- is_one()[source]¶
Return
True
whether this graded Drinfeld form is the multiplicative identity.EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: u = M.one() sage: u.is_one() True sage: (M.0).is_one() False
>>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2)) >>> u = M.one() >>> u.is_one() True >>> (M.gen(0)).is_one() False
A = GF(3)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2) u = M.one() u.is_one() (M.0).is_one()
- is_zero()[source]¶
Return
True
whether this graded Drinfeld form is the additive identity.EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: z = M.zero() sage: z.is_zero() True sage: f = M.0 sage: f.is_zero() False sage: (f - f).is_zero() True sage: (0 * M.0).is_zero() True
>>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2)) >>> z = M.zero() >>> z.is_zero() True >>> f = M.gen(0) >>> f.is_zero() False >>> (f - f).is_zero() True >>> (Integer(0) * M.gen(0)).is_zero() True
A = GF(3)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2) z = M.zero() z.is_zero() f = M.0 f.is_zero() (f - f).is_zero() (0 * M.0).is_zero()
- polynomial()[source]¶
Return this graded Drinfeld forms as a multivariate polynomial over the generators of the ring.
OUTPUT: a multivariate polynomial over the base ring
EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: M.inject_variables() Defining g1, g2 sage: P1 = g1.polynomial(); sage: P2 = g2.polynomial(); sage: P2^2 + P1^2 + P1 g2^2 + g1^2 + g1 sage: P1.parent() 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 * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.inject_variables() Defining g1, g2 >>> P1 = g1.polynomial(); >>> P2 = g2.polynomial(); >>> P2**Integer(2) + P1**Integer(2) + P1 g2^2 + g1^2 + g1 >>> P1.parent() Multivariate Polynomial Ring in g1, g2 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3
A = GF(3)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2) M.inject_variables() P1 = g1.polynomial(); P2 = g2.polynomial(); P2^2 + P1^2 + P1 P1.parent()
The degree of each variables corresponds to the weight of the generator:
sage: P1.degree() 2 sage: P2.degree() 8
>>> from sage.all import * >>> P1.degree() 2 >>> P2.degree() 8
P1.degree() P2.degree()
- rank()[source]¶
Return the rank of this graded Drinfeld form.
Note that the rank is independent of the chosen form and depends only on the parent.
EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M2 = DrinfeldModularForms(K, 2) sage: (M2.0).rank() 2 sage: M5 = DrinfeldModularForms(K, 5) sage: (M5.0 + M5.3).rank() 5
>>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M2 = DrinfeldModularForms(K, Integer(2)) >>> (M2.gen(0)).rank() 2 >>> M5 = DrinfeldModularForms(K, Integer(5)) >>> (M5.gen(0) + M5.gen(3)).rank() 5
A = GF(3)['T']; K = Frac(A) M2 = DrinfeldModularForms(K, 2) (M2.0).rank() M5 = DrinfeldModularForms(K, 5) (M5.0 + M5.3).rank()
- type()[source]¶
Return the type of this graded Drinfeld form.
Recall that the type is the integer \(0 \leq m \leq q-1\) such that
\[f(\gamma(w)) = \mathrm{det}(\gamma)^m j(\gamma, w)^k f(w).\]EXAMPLES:
sage: A = GF(11)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2, has_type=True) sage: M.inject_variables() Defining g1, h2 sage: F = g1*h2^9 sage: F.type() 9 sage: (h2^11).type() 1 sage: g1.type() 0
>>> from sage.all import * >>> A = GF(Integer(11))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2), has_type=True) >>> M.inject_variables() Defining g1, h2 >>> F = g1*h2**Integer(9) >>> F.type() 9 >>> (h2**Integer(11)).type() 1 >>> g1.type() 0
A = GF(11)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2, has_type=True) M.inject_variables() F = g1*h2^9 F.type() (h2^11).type() g1.type()
The type only makes sense when the form is homogeneous:
sage: F = g1^4 + h2 sage: F.type() Traceback (most recent call last): ... ValueError: the graded form is not homogeneous
>>> from sage.all import * >>> F = g1**Integer(4) + h2 >>> F.type() Traceback (most recent call last): ... ValueError: the graded form is not homogeneous
F = g1^4 + h2 F.type()
- weight()[source]¶
Return the weight of this graded Drinfeld modular form.
EXAMPLES:
sage: A = GF(3)['T']; K = Frac(A) sage: M = DrinfeldModularForms(K, 2) sage: M.inject_variables() Defining g1, g2 sage: g1.weight() 2 sage: g2.weight() 8 sage: f = g1^5*g2^2 sage: f.weight() 26
>>> from sage.all import * >>> A = GF(Integer(3))['T']; K = Frac(A) >>> M = DrinfeldModularForms(K, Integer(2)) >>> M.inject_variables() Defining g1, g2 >>> g1.weight() 2 >>> g2.weight() 8 >>> f = g1**Integer(5)*g2**Integer(2) >>> f.weight() 26
A = GF(3)['T']; K = Frac(A) M = DrinfeldModularForms(K, 2) M.inject_variables() g1.weight() g2.weight() f = g1^5*g2^2 f.weight()
If the form is not homogeneous, then the method returns an error:
sage: f = g1 + g2 sage: f.weight() Traceback (most recent call last): ... ValueError: the graded form is not homogeneous
>>> from sage.all import * >>> f = g1 + g2 >>> f.weight() Traceback (most recent call last): ... ValueError: the graded form is not homogeneous
f = g1 + g2 f.weight()