Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Let us take a look at the constructor called in order to build the instance QM2.

First of all, it is mathematically a ring (with further structure),

sage: QM2.category()
Category of graded algebras over Rational Field

If we ask via ?QM2 for more information on the instance, we get...

Type:           QuasiModularForms_with_category
String form:    Ring of Quasimodular Forms for Congruence Subgroup Gamma0(2) over Rational Field
File:           /usr/lib/python3.11/site-packages/sage/modular/quasimodform/ring.py
Docstring:
   The graded ring of quasimodular forms for the full modular group
   \SL_2(\ZZ), with coefficients in a ring.

   EXAMPLES:

      sage: QM = QuasiModularForms(1); QM
      Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
      sage: QM.gens()
      [1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
       1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
       1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)]

   It is possible to access the weight 2 Eisenstein series:

      sage: QM.weight_2_eisenstein_series()
      1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)

   Currently, the only supported base ring is the rational numbers:

      sage: QuasiModularForms(1, GF(5))
      Traceback (most recent call last):
      ...
      NotImplementedError: base ring other than Q are not yet supported for quasimodular forms ring
Init docstring:
   INPUT:

   * "group" (default: \SL_2(\ZZ)) -- a congruence subgroup of
     \SL_2(\ZZ), or a positive integer N (interpreted as \Gamma_0(N)).

   * "base_ring" (ring, default: \QQ) -- a base ring, which should be
     \QQ, \ZZ, or the integers mod p for some prime p.

   * "name" (str, default: "'E2'") -- a variable name corresponding to
     the weight 2 Eisenstein series.

And so on.

We have above also the location of the corresponding py-module on the hard disk, so we have access to the code. This is the open source world. To have the code of the class (starting with the above doc string) also in the interpreter, just ask for ??QM2 instead.

So we have a ring in our hands. When we explicitly ask for this ring, forgetting about everything else...

sage: QM2.polynomial_ring()
Multivariate Polynomial Ring in E2, E2_0, E4_0 over Rational Field

So the ring has three generators,

sage: QM2.polynomial_ring().ngens()
3

and sage uses for them the names E2, E2_0, E4_0. Let us consider the following code:

N = 2
QM = QuasiModularForms(Gamma0(N))

for qm in QM.gens():
    print(f"The q-modular form {qm} has:\n\t"
          f"weight     = {qm.weight()}\n\t"
          f"polynomial = {qm.polynomial()}\n\t"
          f"is_modular = {qm.is_modular_form()}")

It gives:

The q-modular form 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) has:
    weight     = 2
    polynomial = E2
    is_modular = False
The q-modular form 1 + 24*q + 24*q^2 + 96*q^3 + 24*q^4 + 144*q^5 + O(q^6) has:
    weight     = 2
    polynomial = E2_0
    is_modular = True
The q-modular form 1 + 240*q^2 + 2160*q^4 + O(q^6) has:
    weight     = 4
    polynomial = E4_0
    is_modular = True

The names are... see also https://doc.sagemath.org/html/en/reference/modfrm/sage/modular/quasimodform/element.html, when the method polynomial is mentioned:

If the group is not the full modular group, the default names of the generators are given by Ek_i and Sk_i to denote the $i$-th basis element of the weight $k$ Eisenstein subspace, and cuspidal subspace respectively (for more details, see the documentation of polynomial_ring())

And in this last documentation...

sage: QM.polynomial_ring?

Signature:      QM.polynomial_ring(names=None)
Docstring:
   Return a multivariate polynomial ring of which the quasimodular
   forms ring is a quotient.

   In the case of the full modular group, this ring is R[E_2, E_4,
   E_6] where E_2, E_4 and E_6 have degrees 2, 4 and 6 respectively.

   INPUT:

   * "names" (str, default: "None") -- a list or tuple of names
     (strings), or a comma separated string. Defines the names for the
     generators of the multivariate polynomial ring. The default names
     are of the following form:

     * "E2" denotes the weight 2 Eisenstein series;

     * "Ek_i" and "Sk_i" denote the i-th basis element of the weight k
       Eisenstein subspace and cuspidal subspace respectively;

     * If the level is one, the default names are "E2", "E4" and "E6";

     * In any other cases, we use the letters "Fk", "Gk", "Hk", ...,
       "FFk", "FGk", ... to denote any generator of weight k.

   OUTPUT: A multivariate polynomial ring in the variables "names"

   EXAMPLES:
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

there is also a mention about the default convention of denoting elements of the associated polynomial ring.

In fact, replacing above N = 2 and letting the definition of QM use the new N,

N = 24
QM = QuasiModularForms(Gamma0(N))

we obtain a new list of default names:

The q-modular form 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) has:
    weight     = 2
    polynomial = E2
    is_modular = False
The q-modular form 1 + O(q^6) has:
    weight     = 2
    polynomial = E2_0
    is_modular = True
The q-modular form q + O(q^6) has:
    weight     = 2
    polynomial = F2
    is_modular = True
The q-modular form q^2 + O(q^6) has:
    weight     = 2
    polynomial = E2_2
    is_modular = True
The q-modular form q^3 + O(q^6) has:
    weight     = 2
    polynomial = E2_3
    is_modular = True
The q-modular form q^4 + O(q^6) has:
    weight     = 2
    polynomial = E2_4
    is_modular = True
The q-modular form q^5 + O(q^6) has:
    weight     = 2
    polynomial = G2
    is_modular = True
The q-modular form O(q^6) has:
    weight     = 2
    polynomial = E2_5
    is_modular = True
The q-modular form O(q^6) has:
    weight     = 2
    polynomial = E2_6
    is_modular = True

Let us ask for...

sage: QM.polynomial_ring()
Multivariate Polynomial Ring in E2, E2_0, F2, E2_2, E2_3, E2_4, G2, E2_5, E2_6 over Rational Field

And let us decide, we want our own names, using the letter U uniformly.

sage: R = QM.polynomial_ring(names='U')
sage: R
Multivariate Polynomial Ring in U0, U1, U2, U3, U4, U5, U6, U7, U8 over Rational Field
sage: R.inject_variables()
Defining U0, U1, U2, U3, U4, U5, U6, U7, U8

And now we can work with U0, U1, ... , U8 instead.