This section describes routines for working with modular forms and modular form spaces.

Supported modular form *spaces* with corresponding flags are the
following:

***** The full modular form space M_k(Γ_0(N),χ), where k is an
integer and χ a Dirichlet character modulo N (flag 4, the default).

***** The cuspidal space S_k(Γ_0(N),χ) (flag 1).

***** The Eisenstein space ℰ_k(Γ_0(N),χ) (flag 3), so
that M_k = ℰ_k⨁ S_k.

***** The new space S_k^{new}(Γ_0(N),χ) (flag 0).

***** The old space S_k^{old}(Γ_0(N),χ) (flag 2), so that
S_k = S_k^{new}⨁ S_k^{old}.

These spaces are initialized by the `mfinit`

command and contain a basis of
modular forms, which is accessed by the function `mfbasis`

; the elements of
this basis are guaranteed to have Fourier coefficients in the cyclotomic field
ℚ(χ), and no larger.

In addition, since one often works with eigenforms, a space can be
*split*, using the command `mfsplit`

. Because of multiplicity 1,
only a newspace can be split; however for implementation reasons in weight 1
`mfsplit`

of a cuspidal space is tolerated, but the result concerns
only the split of the new space.

The basis of eigenforms is obtained by the function `mfeigenbasis`

:
the elements of this basis now have Fourier coefficients in a relative field
extension of ℚ(χ).

This section describes routines for working with modular forms and modular form spaces.

Returns information about various auto-growing caches. For each ressource, we report its name, its size, the number of cache misses (since the last extension), the largest cache miss and the size of the cache in bytes.

The caches are initially empty, then set automatically to a small inexpensive default value, then grow on demand up to some maximal value. Their size never decreases, they are only freed on exit.

The current caches are

***** Hurwitz class numbers H(D) for |D| ≤ N, computed in time
O(N^{3/2}) using O(N) space.

***** Factorizations of small integers up to N, computed in time
O(N^{1+ϵ}) using O(Nlog N) space.
memory with a large constant (about 16).

***** Divisors of small integers up to N, computed in time
O(N^{1+ϵ}) using O(Nlog N) space.

***** Primitive dihedral forms of weight 1 and level up to N,
computed in time O(N^{2+ϵ}) and space O(N^2).

? getcache() \\ on startup, all caches are empty %1 = [ "Factors" 0 0 0 0] ["Divisors" 0 0 0 0] [ "H" 0 0 0 0] ["Dihedral" 0 0 0 0] ? mfdim([500,1,0],0); \\ non-trivial computation time = 540 ms. ? getcache() %3 = [ "Factors" 50000 0 0 4479272] ["Divisors" 50000 1 100000 5189808] [ "H" 50000 0 0 400008] ["Dihedral" 1000 0 0 2278208]

The library syntax is `GEN `

.**getcache**()

If `mf`

is an eigenform which is already embedded in ℂ, outputs
the corresponding L-function, ready for use with `lfunxxx`

programs.
The binary digits of *flag* mean

***** 1: assume the form is real;

***** 2: assume the form is cuspidal.

If `mf`

is a space, it must be a split new space; output the
vector of `lfuncreate`

s attached to all eigenforms. The result
is a vector whose length is the dimension of the space: each Galois orbit of
dimension d has d corresponding `lfuncreate`

s, one for each
embedding.

? mf = mfsplit([35,2]); F = mfeigenbasis(mf)[2]; mffields(mf) %1 = [z, z^2 - z - 4] ? f = mfembed(F)[2]; ? L = lfunmf(f); ? lfun(L,1) %4 = 0.46007635204895314548435893464149369804 ? [ lfun(L,1) | L <- lfunmf(mf) ] %5 = [0.70291..., 0.81018..., 0.46007...]

The library syntax is `GEN `

.**lfunmf**(GEN mf, long flag, long bitprec)

Mf structure corresponding to the Ramanujan Delta function Δ.

? mfcoefs(mfDelta(),4) %1 = [0, 1, -24, 252, -1472]

The library syntax is `GEN `

.**mfDelta**()

Mf structure corresponding to the standard Eisenstein series E_k.

? mfcoefs(mfEk(8),4) %1 = [1, 480, 61920, 1050240, 7926240]

The library syntax is `GEN `

.**mfEk**(long k)

Given a modular form space `mf`

and a modular form F, returns
the modular form F|W_Q, where W_Q is the Atkink-Lehner involution.
Instead of the primitive divisor Q | N, one can input [M,A], where

M = mfmatatkin(mf, Q, &A);

? mf = mfinit([35,2],0); vecF = mfbasis(mf); F = vecF[1]; ? mfcoefs(F, 4) %2 = [0, 3, -1, 0, 3] ? wF = mfatkin(mf, 7, F); ? mfcoefs(wF, 4) %4 = [0, 1, -1, -2, 7] ? mQ = mfmatatkin(mf, 7); ? mfcoefs(mfatkin(mf, mQ, F), 4) %6 = [0, 1, -1, -2, 7]

The library syntax is `GEN `

.**mfatkin**(GEN mf, GEN F, GEN Q, long bitprec)

Let Q be a primitive divisor of the level N, and let `mf`

be a
split space for (trivial or) quadratic characters defined modulo N/Q.
Outputs the Atkin-Lehner eigenvalues of the eigenforms for the primitive
divisor Q of the level. The result is always ±1 in even weight, and
also ± i in odd weight.

? mf = mfsplit([35,2]); mfatkineigenvalues(mf,5) %1 = [[1], [-1, -1]] ? CHI = Mod(3,4); mf = mfsplit([12,7,CHI]); ? mfatkineigenvalues(mf,3) %3 = [[-I, I, -I, I, -I, I]]

The library syntax is `GEN `

.**mfatkineigenvalues**(GEN mf, long Q, long bitprec)

Basis of the modular form space `mf`

output by `mfinit`

before
splitting, as a vector of modular forms. To obtain the eigenforms, use
`mfeigenbasis`

. If `mf`

is a full space M_k, the output is the
union of first, a basis of the space of Eisenstein series, and second, a
basis of the cuspidal space.

? see(L) = apply(f->mfcoefs(f,3), L); ? mf = mfinit([35,2],0); ? see( mfbasis(mf) ) %2 = [[0, 3, -1, 0], [0, -1, 9, -8], [0, 0, -8, 10]] ? see( mfeigenbasis(mfsplit(mf)) ) %3 = [[0, 1, 0, 1], [Mod(0, z^2 - z - 4), Mod(1, z^2 - z - 4), \ Mod(-z, z^2 - z - 4), Mod(z - 1, z^2 - z - 4)]] ? mf = mfinit([35,2]); ? see( mfbasis(mf) ) %5 = [[1/6, 1, 3, 4], [1/4, 1, 3, 4], [17/12, 1, 3, 4], \ [0, 3, -1, 0], [0, -1, 9, -8], [0, 0, -8, 10]]

The library syntax is `GEN `

.**mfbasis**(GEN mf)

F being an modular form, return B(d)(F), where B(d) is
the expanding operator τ` ⟼ `

dτ.

? D2=mfbd(mfDelta(),2); mfcoefs(D2, 6) %1 = [0, 0, 1, 0, -24, 0, 252]

The library syntax is `GEN `

.**mfbd**(GEN F, long d)

F and G being modular forms, compute the m-th Rankin-Cohen bracket of F and G.

? E4 = mfEk(4); E6 = mfEk(6); ? D1 = mfbracket(E4,E4,2); mfcoefs(D1,5)/4800 %2 = [0, 1, -24, 252, -1472, 4830] ? D2 = mfbracket(E4,E6,1); mfcoefs(D2,10)/(-3456) %3 = [0, 1, -24, 252, -1472, 4830]

The library syntax is `GEN `

.**mfbracket**(GEN F, GEN G, long m)

Compute the n-th Fourier coefficient of the modular form F.
Note that this is the n+1-st component of the vector
`mfcoefs(F,n)`

as well as the second component of `mfcoefs(F,1,n)`

.
By abuse of language, this command also applies to lazy power series as output
by `mfderiv`

.

? mfcoef(mfDelta(),10) %1 = -115920

The library syntax is `GEN `

.**mfcoef**(GEN F, long n)

Compute the vector of Fourier coefficients [a[0],a[d],...,a[nd]] of the
modular form F; d must be positive and d = 1 by default. By abuse of
language, this command also applies to lazy power series as output by
`mfderiv`

.

? D = mfDelta(); ? mfcoefs(D,10) %2 = [0, 1, -24, 252, -1472, 4830, -6048, -16744, 84480, -113643, -115920] ? mfcoefs(D,5,2) %3 = [0, -24, -1472, -6048, 84480, -115920] ? mfcoef(D,10) %4 = -115920

The library syntax is `GEN `

.**mfcoefs**(GEN F, long n, long d)

`mf`

being output by `mfinit`

for the cuspidal space and
F an modular form, gives the smallest level on which F is defined.

? mf=mfinit([96,6],1); vF = mfbasis(mf); mfdim(mf) %1 = 72 ? vector(10,i, mfconductor(mf, vF[i])) %2 = [3, 6, 12, 24, 48, 96, 4, 8, 12, 16]

The library syntax is `long `

.**mfconductor**(GEN mf, GEN F)

Create a modular form from data F. Three types of input are accepted for F:

***** a `t_CLOSURE`

of arity 1: n ` ⟼ `

a(n) computing individual
Fourier coefficients;

***** a `t_CLOSURE`

of arity 2: (n,d) ` ⟼ `

[a(0),a(d),...a(nd)]
computing all coefficients at once in an arithmetic progression;

***** finitely many coefficients, extended by infinitely many zeros; here
we allow a scalar (for c + O(q^n)), a `t_POL`

or `t_SER`

, or a vector
of coefficients.

? f = mfcreate(ramanujantau); mfcoefs(f,5) %1 = [0, 1, -24, 252, -1472, 4830] ? D(n,d) = my(e = eta('x + O('x^(n*d))), v = Vec(e^24)); \ concat(0, vector(n,i,v[i*d])); ? g = mfcreate(D); mfcoefs(g,5) %2 = [0, 1, -24, 252, -1472, 4830] ? N = 10^5; ? mfcoefs(f, N); time = 2,506 ms. ? mfcoefs(g, N); time = 337 ms. ? mfcoefs(mfDelta(), N); time = 186 ms.

The *params* optional argument is of the form
[N,k,χ] and allows to specify the space the form belongs to. An unknown
parameter can be left unspecified by giving it the sentinel value
-1 for the level and weight, and 0 for the character:

? mfparams(f) %7 = [-1, -1, 0] \\ unknown parameters ? F = mfcreate(ramanujantau, [1,12,1]); \\ specify space ? mfparams(F) %7 = [1, 12, 1]

The variant using finitely many coefficients is not as powerful but allows to define a pseudo-modular form when no recipe for the a(n) is known or when many expensive coefficients have been precomputed:

? mfcoefs(mfcreate(2),10) %1 = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ? mfcoefs(mfcreate(3*q+q^2),10) %2 = [0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0] ? mfcoefs(mfcreate([1,2,3,4]),10) %3 = [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0]

The library syntax is `GEN `

.**mfcreate0**(GEN F, GEN params = NULL)

`mf`

being a split space and `cusp`

being an element of P_1(Q)
in the
form oo or a/c with c | N, outputs the coefficients
[a(0), ..., a(n)] giving the Fourier expansion at that cusp. For now, only
for gcd(c,N/c) = 1, and in the expansion ∑ a(j) q^j, the variable q
stands for exp(2π iτ/(N/c)) (and not exp(2π iτ)), since the
width of the cusp is (N/c)/gcd(c,N/c) = N/c.

? mf = mfinit([35,2],0); F = mfbasis(mf)[1]; ? mfcoefs(F, 6) %2 = [0, 3, -1, 0, 3, 1, -8] ? mfcuspexpansion(mf,F,1/5, 6); %3 = [0, 1, -1, -2, 7, 3, -8]

The library syntax is `GEN `

.**mfcuspexpansion**(GEN mf, GEN F, GEN cusp, long n)

In the space defined by `NK = [N,k,CHI]`

or `NK = mf`

,
determine if `cusp`

in canonical format (oo or denominator
dividing N) is regular or not.

? mfcuspisregular([4,3,-4],1/2) %1 = 0

The library syntax is `long `

.**mfcuspisregular**(GEN NK, GEN cusp)

List of cusps of Γ_0(N) in the form a/b with b | N.

? mfcusps(24) %1 = [0, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12, 1/24]

The library syntax is `GEN `

.**mfcusps**(long N)

Width of `cusp`

in Γ_0(N).

? mfcusps(12) %1 = [0, 1/2, 1/3, 1/4, 1/6, 1/12] ? [mfcuspwidth(12,c) | c <- mfcusps(12)] %2 = [12, 3, 4, 3, 1, 1] ? mfcuspwidth(12, oo) %3 = 1

The library syntax is `long `

.**mfcuspwidth**(long N, GEN cusp)

m-th formal derivative of the power series corresponding to the modular form F, with respect to the differential operator qd/dq (default m = 1).

? D=mfDelta(); ? mfcoefs(D, 4) %2 = [0, 1, -24, 252, -1472] ? mfcoefs(mfderiv(D), 4) %3 = [0, 1, -48, 756, -5888]

The library syntax is `GEN `

.**mfderiv**(GEN F, long m)

If F is an modular form of weight k, compute the Serre derivative (q.d/dq)F - kE_2F/12, which corresponds to a modular form of weight k+2, and if m > 1, the m-th iterate.

? mfcoefs(mfderivE2(mfEk(4)),5)*(-3) %1 = [1, -504, -16632, -122976, -532728] ? mfcoefs(mfEk(6),5) %2 = [1, -504, -16632, -122976, -532728]

The library syntax is `GEN `

.**mfderivE2**(GEN F, long m)

If NK = [N,k,*CHI*] as in `mfinit`

, gives the dimension of the
corresponding subspace of M_k(Γ_0(N),χ). NK can also be the
output of `mfinit`

, in which case space must be omitted.

The subspace is described by the small integer `space`

: 0 for the
newspace S_k^{new}(Γ_0(N),χ), 1 for the cuspidal
space S_k, 2 for the oldspace S_k^{old}, 3 for the space of
Eisenstein series E_k and 4 for the full space M_k.

**Wildcards.**
As in `mfinit`

, *CHI* may be the wildcard 0
(all Galois orbits of characters); in this case, the output is a vector of
[*order*,*conrey*,*dim*,*dimdih*] corresponding
to the non-trivial spaces, where

***** *order* is the order of the character,

***** *conrey* its Conrey label from which the character may be recovered
via `znchar`

(*conrey*),

***** *dim* the dimension of the corresponding space,

***** *dimdih* the dimension of the subspace of dihedral forms
corresponding to Hecke characters if k = 1 (this is not implemented for
the old space and set to -1 for the time being) and 0 otherwise.

The spaces are sorted by increasing order of the character; the characters are taken up to Galois conjugation and the Conrey number is the minimal one among Galois conjugates. In weight 1, this is only implemented when the space is 0 (newspace), 1 (cusp space) or 2(old space).

**Wildcards for sets of characters.** *CHI* may be a set
of characters, and we return the set of [*dim*,*dimdih*].

**Wildcard for S_k(Γ_1(N)).**
Additionally, the wildcard *CHI* = -1 is available in which case we
output the total dimension of
S_k(Γ_1(N)). In weight 1, this is only implemented when
the space is 0 (newspace), 1 (cusp space), or 2(old space).

? mfdim([23,2], 0) \\ new space %1 = 2 ? mfdim([96,6], 0) %2 = 10 ? mfdim([10^9,4], 3) \\ Eisenstein space %1 = 40000 ? mfdim([10^9+7,4], 3) %2 = 2 ? mfdim([68,1,-1],0) %3 = 3 ? mfdim([68,1,0],0) %4 = [[2, Mod(67, 68), 1, 1], [4, Mod(47, 68), 1, 1]] ? mfdim([124,1,0],0) %5 = [[6, Mod(67, 124), 2, 0]]

This last example shows that there exists a nondihedral form of weight 1 in level 124.

The library syntax is `GEN `

.**mfdim**(GEN NK, long space)

Given two modular forms F and G, compute F/G assuming
that the quotient will not have poles at infinity. If this is the
case, use `mfshift`

before doing the division.

? D = mfDelta(); \\ Delta ? H = mfpow(mfEk(4), 3); ? J = mfdiv(H, D) *** at top-level: J=mfdiv(H,mfdeltac *** ^-------------------- *** mfdiv: domain error in mfdiv: ord(G) > ord(F) ? J = mfdiv(H, mfshift(D,1)); ? mfcoefs(J, 4) %4 = [1, 744, 196884, 21493760, 864299970]

The library syntax is `GEN `

.**mfdiv**(GEN F, GEN G)

Vector of the eigenforms for the space `mf`

if split, otherwise error.
The initial basis of forms computed by `mfinit`

before splitting
is also available via `mfbasis`

.

? mf = mfsplit([26,2]); ? see(L) = for(i=1,#L,print(mfcoefs(L[i],6))); ? see( mfeigenbasis(mf) ) [0, 1, -1, 1, 1, -3, -1] [0, 1, 1, -3, 1, -1, -3] ? see( mfbasis(mf) ) [0, 2, 0, -2, 2, -4, -4] [0, -2, -4, 10, -2, 0, 8]

The library syntax is `GEN `

.**mfeigenbasis**(GEN mf)

Create the Eisenstein series E_k(χ) (trivial character if omitted) or E_k(χ_1,χ_2), where k ≥ 1 and χ_i are Dirichlet characters.

? CHI = Mod(3,4); ? E = mfeisen(3, CHI); ? mfcoefs(E, 6) %2 = [-1/4, 1, 1, -8, 1, 26, -8] ? CHI2 = Mod(4,5); ? mfcoefs(mfeisen(3,CHI,CHI2), 6) %3 = [0, 1, -1, -10, 1, 25, 10] ? mfcoefs(mfeisen(4,CHI,CHI), 6) %4 = [0, 1, 0, -28, 0, 126, 0] ? mfcoefs(mfeisen(4), 6) %5 = [1/240, 1, 9, 28, 73, 126, 252]

Note that `meisen`

(k) is 0 for k odd and
-B_{k}/(2k).E_k for k even, where
E_k(q) = 1 + ∑_{n ≥ 1} σ_{k-1}(n) q^n
is the standard Eisenstein series. (Thus it is normalized so that its linear
coefficient is 1.)

The library syntax is `GEN `

.**mfeisen**(long k, GEN CHI1 = NULL, GEN CHI2 = NULL)

F being a modular form (usually, but not necessarily, an eigenform),
outputs the vector of forms obtained by substituting the
formal variable of the polmod giving the coefficients of F by all its
embeddings into the complex numbers in the order given by `polroots`

.
This is in particular useful before using mfeval if the coefficients of
F are not rational.

? chi = -4; \\ quadratic char (-4/.) ? mf = mfsplit([32,3,chi]); ? F = mfeigenbasis(mf)[1]; ? mfcoefs(F,3) %4 = [Mod(0, z^2 + 1), Mod(1, z^2 + 1), Mod(0, z^2 + 1), Mod(4*z, z^2 + 1)] ? apply(f->mfcoefs(f,3), mfembed(F)) %5 = [[0, 1, 0, 4*I], [0, 1, 0, -4*I]]

The library syntax is `GEN `

.**mfembed**(GEN F, long prec)

Modular form corresponding to the eta quotient matrix `eta`

, with
a possible power q^a removed: if v is the valuation at infinity
of the eta quotient, then a is the fractional part of v if v ≥ 0,
and a = -v if v < 0, so that in this case the result has valuation 0.

? mfcoefs(mfetaquo(Mat([1,1])),8) %1 = [1, -1, -1, 0, 0, 1, 0, 1, 0] ? mfcoefs(mfetaquo(Mat([1,24])),5) %2 = [0, 1, -24, 252, -1472, 4830, -6048]

The library syntax is `GEN `

.**mfetaquo**(GEN eta)

Computes the numerical value of the modular form F at the complex
number `vtau`

or the vector `vtau`

of complex numbers in the
upper-half plane. If F has polmod coefficients, it must be embedded first
using `mfembed`

.

? mf = mfinit([11,2],0); F = mfbasis(mf)[1]; ? mfeval(F,I/2) %2 = 0.039405471130100890402470386372028382117 ? mf = mfsplit([35,2]); F = mfeigenbasis(mf)[2]; ? mfcoefs(F,2) %5 = [Mod(0, y^2 - y - 4), Mod(1, y^2 - y - 4), Mod(-y, y^2 - y - 4)] ? mfeval(F,I) \\ non rational and not embedded ! *** at top-level: mfeval(mf,F,I) *** ^-------------- *** mfeval: incorrect type in mfeval [use mfembed first] (t_VEC). ? F1 = mfembed(F)[1]; \\ one embedding ? mfeval(F1,I) %7 = 0.0018728717244406706154258944738677007976

The library syntax is `GEN `

.**mfeval**(GEN F, GEN vtau, long bitprec)

If `mf`

(output by `mfinit`

) is a split space with parameters
(N,k,χ), gives the vector of polynomials defining each Galois orbit of
newforms over ℚ(χ).

? mf = mfsplit([35,2]); mffields(mf) %1 = [y, y^2 - y - 4]

Here the character is trivial so ℚ(χ) = ℚ) and there are 3 newforms: one is rational (corresponding to y), the other two are conjugate and defined over the quadratic field ℚ[y]/(y^2-y-4).

? [G,chi] = znchar(Mod(3,35)); ? zncharconductor(G,chi) %2 = 35 ? charorder(G,chi) %3 = 12 ? mf = mfsplit([35, 2, [G,chi]]); mffields(mf) %4 = [y, y]

Here the character is primitive of order 12 and the two newforms are defined over ℚ(χ) = ℚ(ζ_12).

? mf = mfsplit([35, 2, Mod(13,35)]); mffields(mf) %3 = [y^2 + Mod(5*t, t^2 + 1)]

This time the character has order 4 and there are two conjugate newforms over ℚ(χ) = Q(i).

The library syntax is `GEN `

.**mffields**(GEN mf)

E being an elliptic curve defined over Q given by an
integral model in `ellinit`

format, computes a 3-component vector
`[mf,F,coeffs]`

, where F is the newform corresponding to E by
modularity, `mf`

is the split newspace to which F belongs, and
`coeffs`

are the coefficients of F on `mfbasis(mf)`

.

? E = ellinit("26a1"); ? [mf,F,co] = mffromell(E); ? co %2 = [3/4, 1/4]~ ? mfcoefs(F, 5) %3 = [0, 1, -1, 1, 1, -3] ? ellan(E, 5) %4 = [1, -1, 1, 1, -3]

The library syntax is `GEN `

.**mffromell**(GEN E)

L being an L-function in any of the `lfun`

formats representing
a real eigenform, output the corresponding modular form.

This is very primitive implementation and may fail.

? L = lfuncreate(x^2+1); ? L[2..7] %2 = [0, [0, 1], 1, 4, 1, 0] ? lfunan(L,10) %3 = [1, 1, 0, 1, 2, 0, 0, 1, 1, 2] ? -lfun(L,0) %4 = 0.25000000000000000000000000000000000000 ? F = mffromlfun(L); mfparams(F) %5 = [4, 1, -4] ? mfcoefs(F,10) %6 = [1/4, 1, 1, 0, 1, 2, 0, 0, 1, 1, 2]

The library syntax is `GEN `

.**mffromlfun**(GEN L, long prec)

Q being an even integral positive definite quadratic form of
even dimension and P a homogeneous spherical polynomial for Q, computes
a 3-component vector `[mf,F,coeffs]`

, where F is the theta function
corresponding to (Q,P), `mf`

is the corresponding space of modular
forms (from `mfinit`

; so that `mfparams(mf)`

gives level, weight,
character), and `coeffs`

are the coefficients of F on `mfbasis(mf)`

.

? [mf,F,res]=mffromqf(2*matid(10));res %1 = [64/5, 4/5, 32/5]~ ? mfcoefs(F, 5) %2 = [1, 20, 180, 960, 3380, 8424] ? mfcoef(F, 10000); \\ number of ways of writing 10000 as sum of 10 squares %3 = 128205250571893636 ? mfcoefs(F, 10000); \\ very fast ! time = 220ms ? [mf,F,res]=mffromqf([2,0;0,2],x^4-6*x^2*y^2+y^4); ? mfcoefs(F,10) %6 = [0, 4, -16, 0, 64, -56, 0, 0, -256, 324, 224] ? mfcoef(F,100000) \\ almost instantaneous time = 26 ms. %7 = 41304367104

The library syntax is `GEN `

.**mffromqf**(GEN Q, GEN P = NULL)

`NK`

being either `[N,1,CHI]`

or an `mf`

output by
`mfinit`

in weight 1 (split or not), gives the vector of
types of Galois representations attached to each cuspidal eigenform,
unless the modular form `F`

is specified, in which case only for `F`

(not that it is not tested whether `F`

belongs to the correct modular
form space, nor whether it is a cuspidal eigenform). Types A_4, S_4,
A_5 are represented by minus their cardinality -12, -24, or -60,
and type D_n is represented by the integer n:

? mfgaloistype([124,1, Mod(67,124)]) \\ A4 %1 = [-12] ? mfgaloistype([148,1, Mod(105,148)]) \\ S4 %2 = [-24] ? mfgaloistype([633,1, Mod(71,633)]) \\ D10, A5 %3 = [10, -60] ? mfgaloistype([239,1, -239]) \\ D6, D10, D30 %4 = [6, 10, 30] ? mfgaloistype([71,1, -71]) %5 = [14] ? mf = mfsplit([239,1, -239]); F = mfeigenbasis(mf)[2]; ? mfgaloistype(mf, F) %7 = 10

The library syntax is `GEN `

.**mfgaloistype**(GEN NK, GEN F = NULL)

F being a modular form, returns T(n)F, where T(n) is the n-th Hecke operator.

**Warning.** If F is of level M < N, then T(n)F
is in general not the same in M_k(Γ_0(M),χ) and in
M_k(Γ_0(N),χ). Thus, the default is to consider F in the space
given by `mfparams(F)`

, but if you want to specify the space in which
T(n) is taken, add the optional argument `NK = [N,k,CHI]`

.

? mf = mfinit([26,2],0); F = mfbasis(mf)[1]; mftobasis(mf,F) %1 = [1, 0]~ ? G2 = mfhecke(F,2); mftobasis(mf,G2) %2 = [0, 1]~ ? G5 = mfhecke(F,5); mftobasis(mf,G5) %3 = [-2, 1]~ ? G55 = mfhecke(F,5,[130,2]); mftobasis(mf,G55) *** at top-level: mftobasis(mf,G55) *** ^----------------- *** mftobasis: domain error in mftobasis: form does not belong to space

The library syntax is `GEN `

.**mfhecke**(GEN F, long n, GEN NK = NULL)

Create the space of modular forms corresponding to the data contained in
`NK`

and `space`

. `NK`

is a vector which can be
either [N,k] (N level, k weight) corresponding to a subspace of
M_k(Γ_0(N)), or [N,k,*CHI*] (*CHI* a character)
corresponding to a subspace of M_k(Γ_0(N),χ).

The subspace is described by the small integer `space`

: 0 for the
newspace S_k^{new}(Γ_0(N),χ), 1 for the cuspidal
space S_k, 2 for the oldspace S_k^{old}, 3 for the space of
Eisenstein series E_k and 4 for the full space M_k.

**Wildcards.** For given level and weight, it is advantageous to
compute simultaneously spaces attached to different Galois orbits
of characters, especially in weight 1. The parameter *CHI* may be set
to 0 (wildcard), in which case we return a vector of all `mfinit`

(s) of
non trivial spaces in S_k(Γ_1(N)), one for each Galois orbit
(see `znchargalois`

). One may also set *CHI* to a vector of
characters and we return a vector of all mfinits of subspaces of
M_k(G_0(N),χ) for χ in the list, in the same order. In weight 1,
only S_1^{new} and S_1 support wildcards.

The output is a technical structure S, or a vector of structures if
*CHI* was a wildcard, which contains the following information:
[N,k,χ] is given by `mfparams`

(S), the space
dimension is `mfdim`

(S) and a ℂ-basis for the space is
`mfbasis`

(S).

? S = mfinit([36,2], 0); \\ new space ? mfdim(S) %2 = 1 ? mfparams %3 = [36, 2, 1] \\ trivial character ? f = mfbasis(S)[1]; mfcoefs(f,10) %4 = [0, 1, 0, 0, 0, 0, 0, -4, 0, 0, 0] ? vS = mfinit([36,2,0],0); \\ with wildcard ? #vS %6 = 4 \\ 4 non trivial spaces (mod Galois action) ? apply(mfdim,vS) %7 = [1, 2, 1, 4] ? mfdim([36,2,0], 0) %8 = [[1, Mod(1, 36), 1, 0], [2, Mod(35, 36), 2, 0], [3, Mod(13, 36), 1, 0], [6, Mod(11, 36), 4, 0]]

The library syntax is `GEN `

.**mfinit**(GEN NK, long space)

k-th formal integration of the power series corresponding to the modular form F, with respect to the differential operator qd/dq. Only forms with no constant term can be integrated (default k = 1).

? D = mfDelta(); E4 = mfEk(4); ? mfcoefs(mfinteg(D), 4) %1 = [0, 1, -12, 84, -368] ? mfinteg(E4) *** at top-level: mfinteg(E4) *** ^--------------- *** mfinteg: domain error in mfinteg: F(0) != 0 ? mfcoefs(mfinteg(mfshift(E4,-1)), 4) %2 = [0, 1, 120, 720, 1680]

The library syntax is `GEN `

.**mfinteg**(GEN F, long k)

Tests whether the eigenform F is a CM form. The answer
is 0 if it is not, and if it is, either the unique negative discriminant
of the CM field, or the pair of two negative discriminants of CM fields,
this latter case occuring only in weight 1 when the projective image is
D_2 = C_2 x C_2, i.e., coded 4 by `mfgaloistype`

.

? F = mffromell(ellinit([0,1]))[2]; mfisCM(F) %1 = -3 ? mf = mfsplit([39,1,-39]); F=mfeigenbasis(mf)[1]; mfisCM(F) %2 = Vecsmall([-3, -39]) ? mfgaloistype(mf) %3 = [4]

The library syntax is `GEN `

.**mfisCM**(GEN F)

Checks whether the modular forms F is cuspidal or not.

? mfiscuspidal(mfDelta()) %1 = 1 ? mfiscuspidal(mfEk(12)) %2 = 0

The library syntax is `long `

.**mfiscuspidal**(GEN F)

Checks whether the modular forms F and G are equal. If `lim`

is nonzero, only check equality of the first lim+1 Fourier coefficients.

? D = mfDelta(); F = mfderiv(D); ? G = mfmul(mfEk(2), D); ? mfisequal(F, G) %2 = 1

The library syntax is `long `

.**mfisequal**(GEN F, GEN G, long lim)

Checks whether the modular forms F is selfdual or not, in other words if it is an eigenform of the Fricke involution

? mf = mfsplit([35,4]); ? apply(mfisselfdual, mfbasis(mf)) %1 = [0, 0, 0, 0, 0, 0] ? apply(mfisselfdual, mfeigenbasis(mf)) %2 = [1, 1, 1]

The library syntax is `long `

.**mfisselfdual**(GEN F)

`vF`

being a vector of modular forms and `v`

a vector of coefficients of same length, compute the linear
combination of the entries of `vF`

with coefficients `v`

.
**Note.** Use this in particular to subtract two forms F and G
(with vF = [F,G] and v = [1,-1]), or to multiply an form by
a scalar λ (with vF = [F] and v = [λ]).

? D = mfDelta(); G = mflinear([D],[-3]); ? mfcoefs(G,4) %2 = [0, -3, 72, -756, 4416]

The library syntax is `GEN `

.**mflinear**(GEN vF, GEN v)

Matrix of the Atkin-Lehner operator W_Q on the basis formed by
`mfbasis(mf)`

. Implemented only for a split newspace
and real characters defined modulo N/Q.

The function returns a matrix M with rational entries which is a scalar multiple of the true Arkin-Lehner matrix: the latter is M / sqrt{A}. The integer A is a positive or negative divisor A of N, always 1 in even weight.

? mf=mfsplit([32,4]); mfmatatkin(mf, 32, &A) %1 = [5/16 11/2 55/8] [ 1/8 0 -5/4] [1/32 -1/4 11/16] ? A %2 = 1

The library syntax is `GEN `

.**mfmatatkin**(GEN mf, long Q, GEN *A = NULL)

If `vecn`

is an integer, matrix of the Hecke operator T(n) on the
basis formed by `mfbasis(mf)`

. If it is a vecsmall or vector, vector of
such matrices (usually faster than calling each one individually).

? mf=mfinit([32,4],0); mfmathecke(mf,3) %1 = [0 44 0] [1 0 -10] [0 -2 0] ? mfmathecke(mf,[5,7]) %2 = [[0, 0, 220; 0, -10, 0; 1, 0, 12], [0, 88, 0; 2, 0, -20; 0, -4, 0]]

The library syntax is `GEN `

.**mfmathecke**(GEN mf, GEN vecn)

Multiply the two forms F and G.

? E4 = mfEk(4); G = mfmul(mfmul(E4,E4),E4); ? mfcoefs(G, 4) %2 = [1, 720, 179280, 16954560, 396974160] ? mfcoefs(mfpow(E4,3), 4) %3 = [1, 720, 179280, 16954560, 396974160]

The library syntax is `GEN `

.**mfmul**(GEN F, GEN G)

Number of cusps of Γ_0(N)

? mfnumcusps(24) %1 = 8 ? mfcusps(24) %1 = [0, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12, 1/24]

The library syntax is `GEN `

.**mfnumcusps**(GEN N)

Returns `[N,k,CHI]`

, level, weight, and character:
F is either a modular form space or a modular form; in the latter case
the level N may be a multiple of the level of F. If you want the true
level of F from this result, use `mfconductor(mfinit([N,k,CHI]),F)`

.

? E1 = mfeisen(4,-3,-4); E2 = mfeisen(3,5,-7); E3 = mfmul(E1,E2); ? E4 = mfderivE2(E3,3); ? apply(params, [E1,E2,E3,E4]) %1 = [[12, 4, 12], [35, 3, -35], [420, 7, -420], [420, 13, -420]]

In the case of a modular form F which was created via a recipe
for its coefficients (`mfcreate`

), if the level, weight or character
cannot be determined, they are set to the impossible values
-1, -1 or 0 respectively.

The library syntax is `GEN `

.**mfparams**(GEN F)

Period polynomial of the eigenform F. If flag = 1 or -1, odd or even period polynomial. If der > 0, use the der-th derivative of Λ(s) instead of Λ(s) itself in the period polynomial.

? PP=mfperiodpol(mfDelta(),-1);PP/=polcoeff(PP,1);bestappr(PP) %1 = x^9 - 25/4*x^7 + 21/2*x^5 - 25/4*x^3 + x ? PM=mfperiodpol(mfDelta(),1);PM/=polcoeff(PM,0);bestappr(PM) -x^10 + 691/36*x^8 - 691/12*x^6 + 691/12*x^4 - 691/36*x^2 + 1

The library syntax is `GEN `

.**mfperiodpol**(GEN F, long flag, long der, long bitprec)

Basis of period polynomials for weight k. If flag = 1 or -1, basis of odd or even period polynomials.

? mfperiodpolbasis(12,1) %1 = [x^8 - 3*x^6 + 3*x^4 - x^2, x^10 - 1] ? mfperiodpolbasis(12,-1) %2 = [4*x^9 - 25*x^7 + 42*x^5 - 25*x^3 + 4*x]

The library syntax is `GEN `

.**mfperiodpolbasis**(long k, long flag)

Compute F^n, where n is an integer:

? G = mfpow(mfEk(4), 3); \\ E4^3 ? mfcoefs(G, 4) %2 = [1, 720, 179280, 16954560, 396974160]

The library syntax is `GEN `

.**mfpow**(GEN F, GEN n)

F being a modular form (usually, but not necessarily, an eigenform), return the same form where coefficients are now given modulo an absolute polynomial over ℚ, instead of a relative polynomial over ℚ(χ).

The library syntax is `GEN `

.**mfreltoabs**(GEN F, long prec)

Search for a normalized rational eigen cuspform with quadratic character given restrictions on a few initial coefficients. The meaning of the parameters is as follows:

***** `NK`

governs the limits of the search: it is of the form
[N_0,k]: search for all N ≤ N_0, given k, and quadratic
character; note that the character is uniquely determined by (N,k).

***** `AP`

is the search criterion, which can be omitted: a list of
pairs [..., [p,a_p],...], where p is a prime number and a_p is
either a `t_INT`

(the p-th Fourier coefficient must match a_p exactly)
or a `t_INTMOD`

`Mod`

(a,b) (the p-th coefficient must be congruent
to a modulo b).

The result is a vector of 2-component vectors [N,f], where N is the level and f is a form matching the search criteria.

? #mfsearch([80,2],[[2,2],[3,-1]]) %1 = 1 ? #mfsearch([80,2],[[2,2],[5,2]]) %2 = 1 ? v = mfsearch([20,2],[[3,Mod(2,3)],[7,Mod(5,7)]]); #v %3 = 1 ? [N,F]=v[1]; [N,mfcoefs(F,15)] %4 = [11, [0, 1, -2, -1, 2, 1, 2, -2, 0, -2, -2, 1, -2, 4, 4, -1]]

The library syntax is `GEN `

.**mfsearch**(GEN NK, GEN AP = NULL)

Divide the form F by q^s, omitting the remainder if there is one. One can have s < 0.

? D=mfDelta(); mfcoefs(mfshift(D,1), 4) %1 = [1, -24, 252, -1472, 4830] ? mfcoefs(mfshift(D,2), 4) %2 = [-24, 252, -1472, 4830, -6048] ? mfcoefs(mfshift(D,-1), 4) %3 = [0, 0, 1, -24, 252]

The library syntax is `GEN `

.**mfshift**(GEN F, long s)

Identify the modular space mf, as the flag given to `mfinit`

, or
the modular form mf. Returns 0 (newspace), 1 (cuspidal space), 2 (old space),
3 (full space) or 4 (Eisenstein space).

? mf=mfinit([24,4],1);mfspace(mf) %1 = 1 ? mfspace(mfDelta()) %2 = 0 \\ new space

This function returns -1 when it turns out that the function is not actually modular:

? mfspace(mfEk(2)) %3 = -1

The library syntax is `long `

.**mfspace**(GEN mf)

`mf`

from `mfinit`

being in the cuspidal space (either the
newspace or the full cuspidal space), split the space into Galois orbits of
eigenforms of the newspace. As a shortcut, one can input
`mfsplit(NK,...)`

instead of `mfsplit(mfinit(NK),...)`

,
including the 'wildcard' notation for characters, Section se:mfinit; note
that this initializes and splits the newspace: if one requires the
full cuspidal space one must explicitly use
`mfsplit(mfinit(NK,1),...)`

.

The resulting structure is a valid modular form space with extra components:
if now supports `mfeigenbasis`

(list of all eigenforms) and
`mffields`

(list of polynomials defining each Galois orbit).

? mf=mfsplit([11,2]); mfcoefs(mfeigenbasis(mf)[1],16) %1 = [0, 1, -2, -1, ...] ? mf=mfsplit([23,2]); mfcoefs(mfeigenbasis(mf)[1],16) %2 = [Mod(0, z^2 - z - 1), Mod(1, z^2 - z - 1), Mod(-z, z^2 - z - 1), ...] ? mf=mfsplit([179,2]); apply(poldegree, mffields(mf)) %3 = [1, 3, 11] ? L = mfsplit([23, 2, 0]); \\ wildcard notation ? apply(mfparams, L) %5 = [[23, 2, 1], [23, 2, Mod(2, 23)]] \\ two non-trivial spaces ? apply(mfdim, L) %6 = [2, 1]

The library syntax is `GEN `

.**mfsplit**(GEN mf)

`mf`

from `mfinit`

being in the cuspidal space (either the
newspace or the full cuspidal space), split the space into Galois orbits of
eigenforms of the newspace. As a shortcut, one can input
`mfsplit(NK,...)`

instead of `mfsplit(mfinit(NK),...)`

,
including the 'wildcard' notation for characters, Section se:mfinit.

The functions returns [vF, vK], where vF is a vector of (Galois orbit of) eigenforms and vK is a list of polynomials defining each Galois orbit.

If `dimlim`

is set and `mf`

is the
newspace, only the Galois orbits of dimension ≤ `dimlim`

are computed
(i.e. the rational eigenforms if `dimlim`

= 1 and the character is real).
This can considerably speed up the function when a Galois orbit is defined
over a large field. `flag`

is used to avoid long computations when the
dimension is large: if flag = -d < 0, when the dimension of the eigenspace is
> d, only the Galois polynomial is computed. If flag = d > 0, when the
dimension of the eigenspace is > d, the Galois polynomial and a
nonnormalized eigenform is computed.

The resulting structure is *not* a valid modular form space.

? mf=mfsplit([11,2]); mfcoefs(mfeigenbasis(mf)[1],16) %1 = [0, 1, -2, -1, ...] ? mf=mfsplit([23,2]); mfcoefs(mfeigenbasis(mf)[1],16) %2 = [Mod(0, z^2 - z - 1), Mod(1, z^2 - z - 1), Mod(-z, z^2 - z - 1), ...] ? mf=mfsplit([179,2]); apply(poldegree, mffields(mf)) %3 = [1, 3, 11] ? mf=mfsplit([719,2]); \\ slow ! time = 6,881 ms. ? apply(poldegree, mffields(mf)) \\ degree 45 is large %5 = [5, 10, 45] ? mfsplitpartial([719,2], 5); \\ faster when restricting to small orbits time = 1,240 ms.

The library syntax is `GEN `

.**mfsplitpartial**(GEN mf, long dimlim, long flag)

Gives the Sturm bound for modular forms on Γ_0(N) and
weight k, i.e., an upper bound for the order of the zero at infinity of
a nonzero form. `NK`

is either

***** a pair [N,k],

***** or the output of `mfinit`

in which case the exact upper bound
is returned.

? NK = [96,6]; mfsturm(NK) %1 = 97 ? mf=mfinit(NK,1); mfsturm(mf) %2 = 76 ? mfdim(NK,0) \\ new space %3 = 72

The library syntax is `long `

.**mfsturm**(GEN NK)

F being a form in M_k(SL_2(ℤ)), computes the first n+1
canonical Taylor expansion of F around τ = I. If `flreal = 0`

,
computes only an algebraic equivalence class. If `flreal`

is set,
compute p_n such that for τ close enough to I we have
f(τ) = (2I/(τ+I))^k∑_{n >= 0}p_n((τ-I)/(τ+I))^n .

? D=mfDelta(); ? mftaylor(D,8) %2 = [1/1728, 0, -1/20736, 0, 1/165888, 0, 1/497664, 0, -11/3981312]

The library syntax is `GEN `

.**mftaylor**(GEN F, long n, long flreal, long prec)

Coefficients of the form F on the basis given by
`mfbasis(mf)`

. A q-expansion or vector of coefficients
can also be given instead of F, but in this case an error message may occur
if the expansion is too short. An error message is also given if F does not
belong to the modular form space. If `flag`

is set, instead of
error messages the output is an affine space of solutions if a q-expansion
or vector of coefficients is given, or the empty column otherwise.

? mf = mfinit([26,2],0); vtf = mfbasis(mf); ? #vtf \\ dimension 2 %2 = 2 ? F = mflinear(vtf,[a,b]); mftobasis(mf,F) %3 = [a, b]~

A q-expansion or vector of coefficients can also be given instead of F.

? Th = 1 + 2*sum(n=1, 8, q^(n^2), O(q^80)); ? mf = mfinit([4,5,Mod(3,4)]); ? mftobasis(mf, Th^10) %3 = [64/5, 4/5, 32/5]~

If F does not belong to the corresponding space, the result is incorrect
and simply matches the coefficients of F up to some bound, and
the function may either return an empty column or an error message.
If `flag`

is set, there are no error messages, and the result is
an empty column if F is a modular form; if F is supplied via a series
or vector of coefficients which does not contain enough information to force
a unique (potential) solution, the function returns [v,K] where v is a
solution and K is a matrix of maximal rank describing the affine space of
potential solutions v + K.x.

? mf = mfinit([4,12],1); ? mftobasis(mf, q-24*q^2+O(q^3), 1) %2 = [[43/64, -63/8, 800, 21/64]~, [1, 0; 24, 0; 2048, 768; -1, 0]] ? mftobasis(mf, [0,1,-24,252], 1) %3 = [[1, 0, 1472, 0]~, [0; 0; 768; 0]] ? mftobasis(mf, [0,1,-24,252,-1472], 1) %4 = [1, 0, 0, 0]~ \\ now uniquely determined ? mftobasis(mf, [0,1,-24,252,-1472,0], 1) %5 = [1, 0, 0, 0]~ \\ wrong result: no such form exists ? mfcoefs(mflinear(mfbasis(mf),%), 5) \\ double check %6 = [0, 1, -24, 252, -1472, 4830] ? mftobasis(mf, [0,1,-24,252,-1472,0]) *** at top-level: mftobasis(mf,[0,1, *** ^-------------------- *** mftobasis: domain error in mftobasis: form does not belong to space ? mftobasis(mf, mfEk(10)) *** at top-level: mftobasis(mf,mfEk( *** ^-------------------- *** mftobasis: domain error in mftobasis: form does not belong to space ? mftobasis(mf, mfEk(10), 1) %7 = []~

The library syntax is `GEN `

.**mftobasis**(GEN mf, GEN F, long flag)

`mf`

being being the cuspidal space with parameters [N,k,χ]
and F a form in that space, returns a vector of 3-component vectors
[M,d,G], where f(χ) | M | N, d | N/M, and G is a form
in S_k^{new}(Γ_0(M),χ) such that F is equal to the sum of
the B(d)(G) over all these 3-component vectors.

? mf = mfinit([96,6],1); F = mfbasis(mf)[60]; s = mftonew(mf,F); #s %1 = 1 ? [M,d,G] = s[1]; [M,d] %2 = [48, 2] ? mfcoefs(F,10) %3 = [0, 0, -160, 0, 0, 0, 0, 0, 0, 0, -14400] ? mfcoefs(G,10) %4 = [0, 0, -160, 0, 0, 0, 0, 0, 0, 0, -14400]

The library syntax is `GEN `

.**mftonew**(GEN mf, GEN F)

If NK = [N,k,CHI,.] as in `mfinit`

with k != 1, gives the
trace form in the corresponding subspace of S_k(Γ_0(N),χ), i.e. the
newspace (default) or the full cuspidal space if `space`

is set.

? F = mftraceform([23,2]); ? mfcoefs(F,16) %2 = [0, 2, -1, 0, -1, -2, -5, 2, 0, 4, 6, -6, 5, 6, 4, -10, -3]

The library syntax is `GEN `

.**mftraceform**(GEN NK, long space)

F being a modular form, returns the twist of F by the
integer D, i.e., the form G such that
`mfcoef(G,n) = `

(D/n)`mfcoef(F,n)`

, where (D/n) is the Kronecker
symbol.

? mf = mfinit([11,2],0); F = mfbasis(mf)[1]; mfcoefs(F, 5) %1 = [0, 1, -2, -1, 2, 1] ? G = mftwist(F,-3); mfcoefs(G, 5) %2 = [0, 1, 2, 0, 2, -1] ? mf2 = mfinit([99,2],0); mftobasis(mf2, G) %3 = [1/3, 0, 1/3, 0]~

Note that twisting multiplies the level by D^2. In particular it is not an involution:

? H = mftwist(G,-3); mfcoefs(H, 5) %4 = [0, 1, -2, 0, 2, 1] ? mfparams(G) %5 = [99, 2, 1]

The library syntax is `GEN `

.**mftwist**(GEN F, GEN D)

Valuation of the power series corresponding to the form F.

? D=mfDelta();mfval(D) %1 = 1 ? E4=mfEk(4);mfval(E4) %2 = 0 ? E4S=mfshift(E4,-2);mfval(E4S) %3 = 2

The library syntax is `long `

.**mfval**(GEN F)