## Using lcalc to compute half-integral weight L-functions

This is a brief note intended primarily for my collaborators interested in using Rubinstein’s `lcalc`

to compute the values of half-integral weight $L$-functions.

We will be using lcalc through sage. Unfortunately, we are going to be using some functionality which sage doesn’t expose particularly nicely, so it will feel a bit silly. Nonetheless, using sage’s distribution will prevent us from needing to compile it on our own (and there are a few bugfixes present in sage’s version).

Some $L$-functions are inbuilt into lcalc, but not half-integral weight $L$-functions. So it will be necessary to create a datafile containing the data that lcalc will use to generate its approximations. In short, this datafile will describe the shape of the functional equation and give a list of coefficients for lcalc to use.

## Building the datafile

It is assumed that the $L$-function is normalized in such a way that

$$\begin{equation}

\Lambda(s) = Q^s L(s) \prod_{j = 1}^{A} \Gamma(\gamma_j s + \lambda_j) = \omega \overline{\Lambda(1 – \overline{s})}.

\end{equation}$$

This involves normalizing the functional equation to be of shape $s \mapsto 1-s$. Also note that $Q$ will be given as a real number.

An annotated version of the datafile you should create looks like this

```
2 # 2 means the Dirichlet coefficients are reals
0 # 0 means the L-function isn't a "nice" one
10000 # 10000 coefficients will be provided
0 # 0 means the coefficients are not periodic
1 # num Gamma factors of form \Gamma(\gamma s + \lambda)
1 # the \gamma in the Gamma factor
1.75 0 # \lambda in Gamma factor; complex valued, space delimited
0.318309886183790 # Q. In this case, 1/pi
1 0 # real and imaginary parts of omega, sign of func. eq.
0 # number of poles
1.000000000000000 # a(1)
-1.78381067250408 # a(2)
... # ...
-0.622124724090625 # a(10000)
```

If there is an error, lcalc will usually fail silently. (Bummer). Note that in practice, **datafiles should only contain numbers and should not contain comments.** This annotated version is for convenience, not for use.

You can find a copy of the datafile for the unique half-integral weight cusp form of weight $9/2$ on $\Gamma_0(4)$ here. This uses the first 10000 coefficients — it’s surely possible to use more, but this was the test-setup that I first set up.

## Generating the coefficients for this example

In order to create datafiles for other cuspforms, it is necessary to compute the coefficients (presumably using magma or sage) and then to populate a datafile. A good exercise would be to recreate this datafile using sage-like methods.

One way to create this datafile is to explicitly create the q-expansion of the modular form, if we happen to know a convenient expression. For us, we happen to know that $f = \eta(2z)^{12} \theta(z)^{-3}$. Thus one way to create the coefficients is to do something like the following.

```
num_coeffs = 10**5 + 1
weight = 9.0 / 2.0
R.<q> = PowerSeriesRing(ZZ)
theta_expansion = theta_qexp(num_coeffs)
# Note that qexp_eta omits the q^(1/24) factor
eta_expansion = qexp_eta(ZZ[['q']], num_coeffs + 1)
eta2_coeffs = []
for i in range(num_coeffs):
if i % 2 == 1:
eta2_coeffs.append(0)
else:
eta2_coeffs.append(eta_expansion[i//2])
eta2 = R(eta2_coeffs)
g = q * ( (eta2)**4 / (theta_expansion) )**3
coefficients = g.list()[1:] # skip the 0 coeff
print(coefficients[:10])
normalized_coefficients = []
for idx, elem in enumerate(coefficients, 1):
normalized_coeff = 1.0 * elem / (idx ** (.5 * (weight - 1)))
normalized_coefficients.append(normalized_coeff)
print(normalized_coefficients[:10])
```

## Using lcalc now

Suppose that you have a datafile, called `g1_lcalcfile.txt`

(for example). Then to use this from sage, you point lcalc within sage to this file. This can be done through calls such as

```
# Computes L(0.5 + 0i, f)
lcalc('-v -x0.5 -y0 -Fg1_lcalcfile.txt')
# Computes L(s, f) from 0.5 to (2 + 7i) at 1000 equally spaced samples
lcalc('--value-line-segment -x0.5 -y0 -X2 -Y7 --number-samples=1000 -Fg1_lcalcfile.txt')
# See lcalc.help() for more on calling lcalc.
```

The key in these is to pass along the datafile through the `-F`

argument.