This is a late comment on an already accepted good answer from the best source. It just adds sage code, and some few words describe the decisions taken while implementing.
Sooner or later we will need the power series ring $R=\Bbb Q[[q]]$. We can introduce it $(1)$ explicitly as R.<q> = PowerSeriesRing(QQ)
, or $(2)$ get it "for free" after intialization of the needed space of modular forms, then taking one such form, and finally its parent()
. However, the q
variable from one construction is (maybe) not the q
variable from the other one, although in display we see "the same $q$". I will go both ways.
We have also to decide which precision is best suited for the computations.
I will use $200$, since $\Theta$ looks "superlacunary", but when printing elements of the base of the space of modular forms $M(\Gamma_1(4), 1)$ we will truncate to precision $20$. Also, note that sage already provides theta_qexp
, however, since we will focus first on the ring used, we will delay the usage of theta_qexp
for a better control. Hidden things that distinguish between a $\Bbb Q[[q]]$ and a $\Bbb Z[[q]]$ parent should not stay in our way for the start.
$(1)$
N = 200 # default precision below
R.<q> = PowerSeriesRing(QQ, default_prec=N)
theta = sum([q^(n^2) for n in [-isqrt(N)..+isqrt(N)]]) + O(q^N)
MF = ModularForms(Gamma1(4), 3)
print(f'MF is {MF}')
f, g = MF.basis()
And we get (with manual break to fit in page):
MF is Modular Forms space of dimension 2
for Congruence Subgroup Gamma1(4) of weight 3 over Rational Field
Since the dimension is two, and let $f,g$ be the sage generators, we can easily get the answer of representing linearly $\Theta^6$ in terms of $f,g$...
sage: f, g = MF.basis()
sage: f, g
(1 + 12*q^2 + 64*q^3 + 60*q^4 + O(q^6),
q + 4*q^2 + 8*q^3 + 16*q^4 + 26*q^5 + O(q^6))
sage: theta^6 + O(q^6)
1 + 12*q + 60*q^2 + 160*q^3 + 252*q^4 + 312*q^5 + O(q^6)
and it is clearby looking at coefficients in $1$ and $q$ that $\bbox[yellow]{ \Theta^6=f+12g\ }$.
Digression: Also in the general case, sage provides "some order" of the elements of the basis, for instance, without any further comment:
sage: [f.q_expansion(12) for f in CuspForms(Gamma0(6), 8).basis()]
[q + 204*q^6 - 538*q^7 + 96*q^8 - 45*q^9 - 800*q^10 + 3570*q^11 + O(q^12),
q^2 + 63*q^6 - 252*q^7 + 160*q^8 + 216*q^9 - 450*q^10 + 684*q^11 + O(q^12),
q^3 - 8*q^6 + 12*q^9 + O(q^12),
q^4 - 15*q^6 + 42*q^7 - 42*q^8 - 36*q^9 + 140*q^10 - 114*q^11 + O(q^12),
q^5 - 6*q^6 + 15*q^7 - 16*q^8 - 9*q^9 + 48*q^10 - 49*q^11 + O(q^12)]
sage: [f.q_expansion(12) for f in ModularForms(Gamma0(6), 8).basis()]
[q + 204*q^6 - 538*q^7 + 96*q^8 - 45*q^9 - 800*q^10 + 3570*q^11 + O(q^12),
q^2 + 63*q^6 - 252*q^7 + 160*q^8 + 216*q^9 - 450*q^10 + 684*q^11 + O(q^12),
q^3 - 8*q^6 + 12*q^9 + O(q^12),
q^4 - 15*q^6 + 42*q^7 - 42*q^8 - 36*q^9 + 140*q^10 - 114*q^11 + O(q^12),
q^5 - 6*q^6 + 15*q^7 - 16*q^8 - 9*q^9 + 48*q^10 - 49*q^11 + O(q^12),
1 + 480*q^6 + O(q^12),
q - 128*q^4 + 78126*q^5 - 279936*q^6 + 823544*q^7 - 16512*q^8 - 2187*q^9 + 19487172*q^11 + O(q^12),
q^2 + 129*q^4 + 2187*q^6 + 16513*q^8 + 78126*q^10 + O(q^12),
q^3 + 128*q^6 + 2188*q^9 + O(q^12)]
sage:
Can we test in code $\bbox[yellow]{ \Theta^6=f+12g\ }$ ?
For a short answer pointing to the specific danger, let us compare:
sage: theta^6 == f + 12*g
False
sage: theta^6 == (f + 12*g)(q)
True
The False
answer comes from the fact that the parents are different:
sage: (theta^6).parent()
Power Series Ring in q over Rational Field
sage: (f + 12*g).parent()
Modular Forms space of dimension 2 for Congruence Subgroup Gamma1(4) of weight 3 over Rational Field
sage: (theta^6).parent() == (f + 12*g).parent()
False
However, when we use the object $f+12g$ computed in $q$...
sage: ((f + 12*g)(q)).parent()
Power Series Ring in q over Rational Field
To have an analogy with polynomials, let us consider $p\in \Bbb Q[z]$. Then $p$ is a polynomial, but by universality, we can evaluate it in "a point" of a $\Bbb Q$-algebra, which is the "parent". In particular, $p(z)$ is such an evaluation, and $p=p(z)$ formally, the parent is kept. But else, the evaluation changes the parent. In this sense also, when building (f + 12*g)(q)
the parent is changed to the one of q
.
Finally, let us use the $\theta$-function which is also implemented in sage in the above context:
sage: theta_qexp()^6 == f + 12*g
False
sage: theta_qexp()^6 == (f + 12*g)(q)
True
$(2)$ Let us do the same by using the parent provided by the constructed modular forms in the basis. We mention only the differences that occur.
MF = ModularForms(Gamma1(4), 3, prec=44)
print(f'MF is {MF}')
f, g = MF.q_expansion_basis() # already power series
R = f.parent()
print(f"R is {R}")
print(f"R has default precision {R.default_prec()}")
R.inject_variables() # defines q
And we obtain:
MF is Modular Forms space of dimension 2
for Congruence Subgroup Gamma1(4) of weight 3 over Rational Field
R is Power Series Ring in q over Rational Field
R has default precision 20
However, when printing f
we obtain it with the declared precision 44
:
1 + 12*q^2 + 64*q^3 + 60*q^4 + 160*q^6 + 384*q^7 + 252*q^8 + 312*q^10
+ 960*q^11 + 544*q^12 + 960*q^14 + 1664*q^15 + 1020*q^16 + 876*q^18
+ 2880*q^19 + 1560*q^20 + 2400*q^22 + 4224*q^23 + 2080*q^24 + 2040*q^26
+ 5248*q^27 + 3264*q^28 + 4160*q^30 + 7680*q^31 + 4092*q^32 + 3480*q^34
+ 9984*q^35 + 4380*q^36 + 7200*q^38 + 10880*q^39 + 6552*q^40
+ 4608*q^42 + 14784*q^43 + O(q^44)
Now we can use the injected q
from the ring R
, which has unfortunately uncontrolled precision, it is still 20
, as printed above. (And the $q$-expansion of $f$ is computed to higher precision, without giving us access to the parent inside this computation.)
Then we define theta
, and check the relation $\Theta^6=f+12g$...
sage: theta = sum([q^(n^2) + O(q^44) for n in [-10..10]])
....: theta^6 == f + 12*g
....:
True
Also:
sage: theta_qexp()^6 == f + 12*g
True
(Note that now on the R.H.S. we did not evaluate in $q$.)
It remains to address the general question, $(3)$, given a $q$-series $F$ and a potential space of modular forms $M$ where it is / may be inside, can we check if $F$ is indeed in $M$, and if this is the case to compute $F$ as a linear combination in terms of the offered basis?
Yes, this is a linear algebra problem that can be easily implemented. But we also have support!
We use theta_qexp()^6
, and try to see if it is in the claimed modular forms space MF
. Here is the really short code for this:
MF = ModularForms(Gamma1(4), 3, prec=8)
try:
F = MF(theta_qexp()^6)
print(f'OK!\nF = {F}\nis a modular form in the space\nMF = {MF}\n\n')
print(f'Coefficients w.r.t. the basis of MF:\n{MF.coordinate_vector(F)}')
except:
import traceback
traceback.print_exc()
And we get:
OK!
F = 1 + 12*q + 60*q^2 + 160*q^3 + 252*q^4 + 312*q^5 + 544*q^6 + 960*q^7 + O(q^8)
is a modular form in the space
MF = Modular Forms space of dimension 2 for Congruence Subgroup Gamma1(4) of weight 3 over Rational Field
Coefficients w.r.t. the basis of MF:
(1, 12)
To see the main used function explicitly, not inside an f
-formatted string:
sage: F
1 + 12*q + 60*q^2 + 160*q^3 + 252*q^4 + 312*q^5 + 544*q^6 + 960*q^7 + O(q^8)
sage: MF.coordinate_vector(F)
(1, 12)
Let us see the same story inside an other example, where we specialize
the symmetric two variables Ramanujan series
$$
f = 1 + (a+b) + (a^2+b^2)(ab) + (a^3+b^3)(ab)^3 + (a^4+b^4)(ab)^6 + \dots
$$
in $(q,q)$, take some power, and "guess" a space of modular forms where it could live in, and check this inside a search loop.
When found, we want the coefficients.
R.<a,b> = PowerSeriesRing(QQ, default_prec=400)
f = 1 + sum([(a^n + b^n)*(a*b)^ZZ(n*(n-1)/2) + O(a, b)^400 for n in [1..20]])
S.<q> = PowerSeriesRing(QQ, default_prec=400)
g = f(q, q)^16
for k in [1..10]:
MF = ModularForms(Gamma1(4), k)
if MF.dimension() == 0: continue # with the next k
try:
G = MF(g)
print(f'g = f(q, q)^2 is an element of:\n{MF}')
print(f'Its coefficients w.r.t. the base of this space:')
print(MF.coordinate_vector(G))
except:
pass
And we get (with manual breaks):
g = f(q, q)^2 is an element of:
Modular Forms space of dimension 5
for Congruence Subgroup Gamma1(4) of weight 8 over Rational Field
Its coefficients w.r.t. the base of this space:
(512/17, 4096/17, 1, 32/17, 4064/17)
An other example involves eta-products.
We consider:
$$
f =
\eta(\; z\; )^6
\cdot\eta(\; 2z\; )^{-3}
\cdot\eta(\; 3z\; )^{-2}
\cdot\eta(\; 4z\; )^7
\cdot\eta(\; 6z\; )
\cdot\eta(\; 8z\; )^{-2}
\cdot\eta(\; 12z\; )^7
\cdot\eta(\; 24z\; )^{-2}\ .
$$
Is this a modular form? It is useful to introduce the data in a dictionary:
dic = {1:6, 2:-3, 3:-2, 4:7, 6:1, 8:-2, 12:7, 24:-2}
Now we define with bare hands (so that no hidden functionality may come into play):
R.<q> = PowerSeriesRing(QQ, default_prec=100)
e = prod([1 - q^n + O(q^101) for n in [1..100]]) # and q^(1/24) is missing
f = prod([e(q^j)^k for j, k in dic.items()])
g = q^ZZ(sum([j*k for j, k in dic.items()])/24) * f # add the missing part
CF = CuspForms(Gamma0(24), 6, prec=100)
try:
G = CF(g)
print(f'OK G = {G(q) + O(q^10)} is in the space CF:\n{CF}')
print(f'Its coefficients w.r.t. the base of CF are:')
print(CF.coordinate_vector(G))
except:
print('*** Bad news is not good news in maths***')
And we get (manually rearranged):
OK G = q^2 - 6*q^3 + 12*q^4 - 6*q^5 - 13*q^6 + 42*q^7 - 72*q^8 + 30*q^9 + O(q^10) is in the space CF:
Cuspidal subspace of dimension 16
of Modular Forms space of dimension 24
for Congruence Subgroup Gamma0(24) of weight 6 over Rational Field
Its coefficients w.r.t. the base of CF are:
(0, 1, -6, 12, -6, -13, 42, -72, 30, 70, -102, 108, -12, -200, 114, -108)
And the basis is...
sage: CF.q_expansion_basis(prec=30)
[
q + 48*q^19 + 114*q^21 - 312*q^23 - 491*q^25 + 120*q^27 + 1092*q^29 + O(q^30),
q^2 + 39*q^18 - 192*q^22 + 90*q^26 + O(q^30),
q^3 + 30*q^19 - 40*q^21 - 72*q^23 - 120*q^25 + 69*q^27 + 288*q^29 + O(q^30),
q^4 + 4*q^16 - 30*q^20 - 36*q^24 + 68*q^28 + O(q^30),
q^5 - 20*q^19 + 27*q^21 - 24*q^23 - 82*q^25 + 48*q^27 + 147*q^29 + O(q^30),
q^6 - 12*q^18 + O(q^30),
q^7 - 7*q^19 - 60*q^21 + 42*q^23 + 188*q^25 - 66*q^27 - 336*q^29 + O(q^30),
q^8 - 6*q^16 + 9*q^24 + O(q^30),
q^9 - 20*q^19 - 14*q^21 + 48*q^23 + 80*q^25 - 40*q^27 - 192*q^29 + O(q^30),
q^10 - 15*q^18 + 38*q^22 - 42*q^26 + O(q^30),
q^11 - 11*q^19 - 24*q^21 + 38*q^23 + 104*q^25 - 45*q^27 - 224*q^29 + O(q^30),
q^12 - 4*q^16 + 4*q^20 + 4*q^24 - 12*q^28 + O(q^30),
q^13 - 7*q^19 - 15*q^21 + 24*q^23 + 64*q^25 - 30*q^27 - 138*q^29 + O(q^30),
q^14 - 6*q^18 + 15*q^22 - 20*q^26 + O(q^30),
q^15 - 5*q^19 - 4*q^21 + 12*q^23 + 20*q^25 - 12*q^27 - 48*q^29 + O(q^30),
q^17 - q^19 - 6*q^21 + 4*q^23 + 19*q^25 - 6*q^27 - 38*q^29 + O(q^30)
]
(Note also how easy it is to see the first coefficients of the cusp form $G=q^2 -6q^3+12q^4+\dots$ in terms of the base chosen in sage, with elements of the shape $q^k+\dots$ with $k$ from $1$ to $17$, missing only the $16$, and with a $q^{16}$ part only for $k$ divisible by four. Else only terms in the ideal $O(q^{18})$.)