Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The answer of FrédéricC is already wonderful, here is maybe a way to make your own way in the next similar situation. First of all, let us consider the code:

G = DirichletGroup(7, QQ)                                                                                               
S = CuspForms(e, 3, prec=20)                                                                                            
g = S.gens()[0]                                                                                                         
print( f"g = {g}" )
R = g.qexp().parent()
print( f"R = {R}\nIts default precision is {R.default_prec()}" )
q = R.gen()

L = EtaProduct(7, {1:4, 7:-4})
print( f"L = {L}" )

The above gives

g = q - 3*q^2 + 5*q^4 - 7*q^7 - 3*q^8 + 9*q^9 - 6*q^11 + 21*q^14 - 11*q^16 - 27*q^18 + O(q^20)
R = Power Series Ring in q over Rational Field
Its default precision is 20
L = Eta product of level 7 : (eta_1)^4 (eta_7)^-4

Now i noted that the method L.qexp needs an argument. At least for me in my version. This can be seen / asked in the ipython interpreter for sage as follows...

sage: L.qexp?                                                                                                                 
Signature:      L.qexp(n)
Docstring:     
   Alias for "self.q_expansion()".

   EXAMPLES:

      sage: e = EtaProduct(36, {6:8, 3:-8})
      sage: e.qexp(10)
      q + 8*q^4 + 36*q^7 + O(q^10)
      sage: e.qexp(30) == e.q_expansion(30)
      True
Init docstring: Initialize self.  See help(type(self)) for accurate signature.
File:           /usr/lib/python3.8/site-packages/sage/modular/etaproducts.py
Type:           method
sage:

and the above L.qexp goes to the doc string of the method qexp in the class L is an instance for:

sage: L.__class__                                                                                                             
<class 'sage.modular.etaproducts.EtaGroupElement'>

So we really need an argument for it in my version.

sage: version()                                                                                                               
'SageMath version 9.0, Release Date: 2020-01-01'

In my case L.qexp() produces an error, since one argument is needed, but this is easily corrected, L.exp(20) would be ok. Since the precision of the series for $g$ is $20$, we should use the same precision... Well:

sage: L.qexp(20)                                                                                                              
q^-1 - 4 + 2*q + 8*q^2 - 5*q^3 - 4*q^4 - 10*q^5 + 12*q^6 - 7*q^7 + 8*q^8 + 46*q^9 - 36*q^10 - 26*q^11 - 44*q^12 + 46*q^13 - 28*q^14 + 42*q^15 + 188*q^16 - 132*q^17 - 96*q^18 + O(q^19)
sage: g.qexp()                                                                                                                
q - 3*q^2 + 5*q^4 - 7*q^7 - 3*q^8 + 9*q^9 - 6*q^11 + 21*q^14 - 11*q^16 - 27*q^18 + O(q^20)

and the series are stopping at the "multiplicative precision" equal to $20$. For $L$ we have an expression modulo $O(q^{19})$ (since it starts with $1/q$), for $g$ we have an expression modulo $O(q^{20})$ . This situation may lead to losing the initial precision.

Now i tried:

  • g + O(q^6), but it fails. (Although fL + O(q^6) works.)
  • g * fL, but it fails. (Although g(q) * fL works.)

To make things work, replace g by g(q)...


So finally, the following code does the job for me. Framework:

PREC = 20
G = DirichletGroup(7, QQ)
S = CuspForms(e, 3, prec=PREC)
g = S.gens()[0]
R = g.qexp().parent()
q = R.gen()

L = EtaProduct(7, {1:4, 7:-4})
fL = L.qexp(PREC)

g(q) * (fL + 4)(q) + O(q^6)

(Addition, multiplication, and truncation work.) Final result:

1 - 3*q + 2*q^2 + 7*q^3 - 29*q^4 + 21*q^5 + O(q^6)