The Graded Ring of Modular Forms in SageMath
Published:
The goal of this post is to go over some of the new features that are currently in developement for the graded ring of modular forms in SageMath.
Currently in SageMath (version 9.3), it is possible to create the graded ring of modular forms using the class ModularFormRing:
However, this class does not follows the parent structure offered by SageMath. This feature is useful when implementing a new algebraic structure in SageMath and I will explain why here. Some knowledge of the python programming language will be assumed.
Some mathematics
First of all, the graded ring of modular forms is the set of all modular forms for a given group. More precisely, it consist of the direct sum
\[\mathcal{M}_*(\Gamma) := \bigoplus_{k\in \mathbb{Z}} \mathcal{M}_k(\Gamma),\quad \Gamma \leq \mathrm{SL}_2(\mathbb{Z}).\]Note that we have
\[\mathcal{M}_{k_1}(\Gamma) \mathcal{M}_{k_2}(\Gamma) \subseteq \mathcal{M}_{k_1+k_2}(\Gamma), k_1, k_2\in \mathbb{Z}.\]We will view an element \(F\) of \(\mathcal{M}_*(\Gamma)\) as a sum
\[F = f_0 + f_1 + f_2 + \ldots + f_r, \quad r\geq 0,\]where each \(f_k\) is a weight \(k\) modular forms. Such an element \(F\) will be called a graded modular form (or sometimes simply a graded form). Note that it is not garanteed that a graded form is a modular form as it is not always invariant under the slash-\(k\) operator. For example, take the function
\[F := E_4 + E_6\]where \(E_4\) and \(E_6\) are the weight \(4\) and \(6\) normalized Eisenstein series.
Given a graded form \(F = f_0 + f_1 + f_2 + \ldots + f_r\), each modular forms \(f_k\) will be called the weight \(k\) homogeneous component of \(F\).
Some programming
In SageMath, there is a notion of elements and parents. In short, an element is a member contained in a structure called parent. An example of a parent in SageMath is the ring of integer \(\mathbb{Z}\) with elements the integers. To implement a new parent structure in SageMath, one need to define a class that inherit of the subclass Parent. This was not the case for the initial implementation of the class ModularFormRing.
Moreover, when implementing a new structure, one needs to also define a new class representing the elements of our parent class. This class of elements must inherit of the subclass Element. The base methods of this subclass provides useful features. For example, when implemented correctly, it is possible to define the classical operations (addition, multiplication,…) between our elements.
Implementing this Parent/Element framework is exactly what we want to do here with the class ModularFormsRing
.
New features
It is now possible to work with a graded modular forms element:
We observe here that E4
and e4
are the same mathematical object but does not lives in the same parent. An interaction between these two parents can be implemented and this is what we call coercion. This will be explained a little bit later in the current post.
Here’s an overview of what was done in order to make the above example works:
- Make the class
ModularFormRing
inherit fromParent
; - Define a specific element class (
GradedModularFormElement
); - Define the
_element_constructor_
method; - Define coercions between
ModularFormSpace
andModularFormRing
Below is a summary of the class ModularFormRing
with its _element_constructor_
method.
Here is a brief summary of the element class GradedModularFormElement
:
We have chosen here to represent a graded modular form as a dictionnary because this makes it easier to access the weight-\(k\) component of the graded form (keys = weights, values = modular forms).
Now that the Parent/Element framework is implemented, it is also desirable to define operation between two GradedModularFormElement
. This is done by defining the three special methods: _add_
, _neg_
and _mul_
.
These three methods provides now the possibility of adding, substracting and multiplying two graded forms in SageMath:
For the last part of this post, I will cover briefly the notion of “coercion” which is an important part of this implementation. Thanks to the coercion framework in SageMath, it is possible to implement some interactions between two different parents. For example, one could want to perform an operation between a ModularFormElement
and a GradedModularFormElement
.
To implement this useful feature it is sufficient to implement the method _coerce_map_from_
to the class ModularFormRing
and the coercion framework of SageMath will take care of the rest.
Finally, in the near future, I plan to implement the “pushout” of two different ModularFormsSpace
. In other words, this functionality would add the possibility to sum two ModularFormElement
of different weight and create directly a GradedModularFormElement
. For example, we currently (v. 9.3) have the following behavior:
Instead of an error here, SageMath would return a GradedModularFormElement
. This feature is still under developpement.
Thanks for reading!