General L-series

In addition to the built-in L-series for the standard objects, Magma provides machinery that allows the user to define L-series for arbitrary objects, provided that they admit a meromorphic continuation to the whole complex plane and satisfy a functional equation of the standard kind. To describe how this may be done, we need to introduce some terminology.

Contents

Terminology

Recall that an L-series is a sum

L(s) = ∑n=1^∞(an/ns),

where the coefficients an are complex numbers, known as the Dirichlet coefficients of the L-series. For example, the Dirichlet coefficients of the classical Riemann zeta function are an=1 for all n. We assume that, as in the case of Riemann zeta function, every L(s) has a meromorphic continuation to the complex plane and has a functional equation. Technically, our assumptions are as follows:

Assumption 1. The defining series for L(s) converges for Re(s) sufficiently large. Equivalently, the coefficients an grow at worst as a polynomial function of n.

Assumption 2. L(s) admits a meromorphic continuation to the entire complex plane.

Assumption 3. The following exist: real positive weight, complex sign of absolute value 1, real positive conductor and the Γ-factor γ(s) = Γ((s + λ1)/2) ... Γ((s + λd)/2) of dimension d≥1 and rational γ-shifts λ1, ... λd, such that

L * (s)=(((conductor)/πd))s/2 γ(s) L(s)

satisfies the functional equation

L * (s) = (sign) .bar L * ((weight) - s).

Here bar L is the dual L-series with complex conjugate coefficients L(s)=∑n=1^∞/line(an)/ns. Note that the "weight" here is one more than the usual motivic notion of weight.

Assumption 4. The series L * (s) has finitely many simple poles and no other singularities.

Assumption 1 will almost certainly be true for any naturally arising L-function and Assumptions 2--4 are expected (but not proven) to be satisfied for most of the L-functions arising in geometry and number theory. In fact, there is a large class of so-called motivic L-functions for which all of the above assumptions are conjectured to be true. Essentially this class consists of L-functions associated to cohomology groups of varieties over number fields. This is an extremely large class of L-functions that includes all of the standard examples.

Constructing a General L-Series

When computing the values L(s) for a complex number s, Magma relies heavily on the functional equation. This means that the emphasized parameters in Assumptions 1--4 (coefficients, weight, conductor, poles, etc.) must be known before the computations can be carried out.

The generic LSeries function allows the user to construct an L-series for a new object by specifying values for these parameters. In fact, this function is used to construct all of the built-in L-series in Magma and some of these will be used as examples to illustrate its use (see the advanced examples section).

LSeries(weight, gamma, conductor, cffun) : FldReElt,[FldRatElt],FldReElt,Any -> LSer
    Sign: FldComElt                     Default: 0
    Poles: SeqEnum                      Default: []
    Residues: SeqEnum                   Default: []
    Parent: Any                         Default: 
    CoefficientGrowth: UserProgram      Default: 
    Precision: RngIntElt                Default: 
    ImS: FldReElt                       Default: 0
    Asymptotics: BoolElt                Default: true
LSeries(HS, N, cffun) : HodgeStruc, RngIntElt, Any -> LSer
This is an alternative way to specify a generic L-series, with all the varargs of before. Instead of giving a real number for the functional equation reflection together with γ-shifts, one passes a Hodge structure to the LSeries intrinsic instead.

For more examples, see the "Advanced Examples" Section Advanced Examples.

It is strongly advised that whenever a generic L-series is defined the user apply one of the functions CFENew or CheckFunctionalEquation. If one of the specified parameters (conductor, sign, etc.) happens to be incorrect, the resulting L-series will not have a functional equation and the values returned by the evaluation functions will be nonsense. Only by checking the functional equation will the user have an indication that something is wrong.

CheckFunctionalEquation(L) : LSer -> FldComElt
CFENew(L) : LSer -> FldReElt
    t: FldReElt                         Default: 1.2
Given an L-series L, this intrinsic tests the functional equation numerically and should ideally return 0 (to the current precision), meaning that the test was passed.

The new preferred version is CFENew, which in many cases of reasonable interest can often require signficantly fewer terms (using a dynamic criterion, rather than a static one), sometimes by a factor of 5 or more. It also is much superior at keeping track of internal precision. However, it does not completely replicate the old machinery (particularly when poles/residues are present), and so CheckFunctionalEquation is also still available.

If the value returned is a significant distance from 0, either the L-function does not have a functional equation or some of the defining parameters (conductor, poles etc.) have been incorrectly specified or not enough coefficients have been given. In the latter case, CFENew or CheckFunctionalEquation is likely to return a number reasonably close to 0 that measures the accuracy of computations.

As already mentioned, Magma can only work with L-functions that satisfy the functional equation as in Section Terminology. Whenever an L-function is constructed, its functional equation is implicitly used in all the L-series evaluations, even when L is evaluated in the region where the original Dirichlet series is absolutely convergent.

If either the sign in the functional equation or the residues of L * (s) have not yet been computed, this function will first compute them. If the sign was undefined, it returns |Sign| - 1 which, again, must be 0.

The optional technical parameter t is a point on the real line where Magma evaluates the two Theta functions associated to the L-series and subtracts one from the other to get the value returned by CFENew or CheckFunctionalEquation.

Example Lseries_lseries-checkfun (H136E19)

We attempt to define a truncated L-series of a quadratic character mod 3 (so χ(n) =0, 1, - 1 if n is 0, 1 or 2 mod 3 respectively.)
> L := LSeries(1, [0], 3, [1,-1,0,1,-1,0] : Sign:=-1);
> CFENew(L);
0.222346257403989419245646558069
This does not look right. In fact, the γ-shifts are 0 for even quadratic characters, but 1 for odd ones,
> L := LSeries(1, [1], 3, [1,-1,0,1,-1,0] : Sign:=-1);
> CheckFunctionalEquation(L);
1.06372623587922089871296822624
> CFENew(L);
7.47942058598558334301138589732E-18
This still does not look right (though CFENew will ignore Sign). We gave the wrong sign in the functional equation.
> L := LSeries(1, [1], 3, [1,-1,0,1,-1,0] : Sign:=1);
> CFENew(L);
7.47942058598558334301138589732E-18
This certainly looks better but it indicates that we did not give enough coefficients to our L-series. We determine how many coefficients are needed to do computations with default precision (30 digits),
> LCfRequired(L); // approx for old CheckFunctionalEquation
11

So 11 coefficients are needed and we provide them in the code below.

> L := LSeries(1, [1], 3, [1,-1,0,1,-1,0,1,-1,0,1] : Sign:=1);
> CFENew(L);
0.000000000000000000000000000000

This a correct way to define our L-series. Even better is the following variant:

> L := LSeries(1, [1], 3, func<n|((n+1) mod 3)-1> : Sign:=1);
> CFENew(L);
0.000000000000000000000000000000

This allows Magma to calculate as many an as it deems necessary using the provided function.

Setting the Coefficients

LSetCoefficients(L,cffun) : LSer, Any ->
This function defines the coefficients an of the L-series L. The argument cffun can be one of the following:
A sequence [a1, ..., an];

A function f(n) that returns an;

A function f(p, d) that computes the inverse of the local factor at p up to degree d.

When a user-defined L-series is constructed by invoking the function

> L := LSeries(weight,gamma,conductor,cffun: <optional parameters>);
this is actually equivalent to invoking the pair of functions
> L := LSeries(weight,gamma,conductor,0: <optional parameters>);
> LSetCoefficients(L,cffun);
where the first line indicates that the coefficients will be supplied later and the second line actually specifies the coefficients. So the following description of the cffun argument for the function LSetCoefficients(L,cffun) applies to the main LSeries signature as well.

The first two ways to specify the an are either to give a pre-computed sequence of coefficients up to a certain bound or to give the name of a function f(n) that computes the an. (The other two ways are described in the two subsections that follow.) For instance, the following both define the Riemann zeta function with weight 1, one γ-shift 0, conductor 1, sign 1, pole at s=1 with residue -1, all an=1:

> V := [ 1 : k in [1..100] ];
> L := LSeries(1, [0], 1, V : Sign:=1, Poles:=[1], Residues:=[-1]);
or
> f := func<n|1>;
> L := LSeries(1, [0], 1, f : Sign:=1, Poles:=[1], Residues:=[-1]);

Of the two possibilities, the second one is safer to use in a sense that it lets Magma decide how many coefficients it needs in order to perform the calculations to the required precision. However, if the computation of an is costly and it involves previous coefficients, then it is probably better to write a function that computes an recursively, storing them in a sequence and then passing it to LSeries.

Specifying the Coefficients Later

When specifying a finite list of coefficients it is necessary to know in advance how many coefficients have to be computed. For this, Magma provides a function LCfRequired(L) (see Section Accessing the Invariants).

Example Lseries_lseries-lcfrequired (H136E20)

We define L to be our own version of the Riemann zeta function (weight 1, one γ-shift 0, conductor 1, sign 1, pole at s=1 with residue -1), but tell Magma that we will specify the coefficients later with the 4th parameter set to 0. Then we ask how many coefficients it needs to perform computations:
> L := LSeries(1, [0], 1, 0: Sign:=1, Poles:=[1], Residues:=[-1]);
> N := LCfRequired(L); N;
6
Now we compute the coefficient vector [a1, ..., aN].
> vec := [1, 1, 1, 1, 1, 1];
> LSetCoefficients(L,vec);
Now we can evaluate our ζ-function
> Evaluate(L,2);
1.64493406684822643647241516665
> Pi(RealField())^2/6;
1.64493406684822643647241516665
If we provide fewer coefficients, the computations will not have full precision but we can use CFENew or CheckFunctionalEquation to get an indication of the resulting accuracy.
> LSetCoefficients(L, [1,1]);
> CFENew(L);
1.49504837351354351195383363489E-10
> Evaluate(L, 2);
1.64493406707833102002503055804
> $1 - Pi(RealField(28))^2/6;
2.301045835526153913058838556E-10
Note that such good accuracy with just two coefficients is a singular phenomenon that only happens for L-functions with very small conductors. Normally, at least hundreds of coefficients are needed to compute L-values to this precision.

Note also that the last value Evaluate(L,2) in the example is much more precise than what one would get with the truncated version of the original defining series ζtrunc(s)=1 + 1/2s at s=2. The reason for this is that even in the region where the original Dirichlet series converges, the use of the functional equation usually speeds up the convergence.

Generating the Coefficients from Local Factors

The final and, in many cases, mathematically the most natural way to supply the coefficients is by specifying the so-called local factors. Recall that the coefficients for most L-series are weakly multiplicative, meaning that amn=aman for m coprime to n. For such L-series, L(s) admits a product formula

L(s) = ∏_(p (prime)) (1/Fp(p - s)),

where Fp(x) is a formal power series in x with complex coefficients. For example, if L(s) arises from a variety over a number field (and this, as we already mentioned, essentially covers everything), then such a product formula holds. In this case the Fp(x) are polynomials of degree d for those primes p not dividing the conductor and are of smaller degree otherwise. Moreover, their coefficients lie in the ring of integers of the field of definition of the variety.

For L-functions with weakly multiplicative coefficients, Magma allows the coefficients to be defined by specifying the local factors, using the function LSetCoefficients(L,f) where f is a user-defined function with two arguments p and d that computes Fp(x), either as a full polynomial in x or as a power series in x of precision O(xd + 1). For example, the Riemann zeta function has Fp(x)=1 - x for all p, so we can define it as follows,

> Z := LSeries(1, [0], 1, 0 : Poles:=[1], Residues:=[-1], Sign:=1);
> P<x> := PolynomialRing(Integers());
> LSetCoefficients(Z, func<p,d | 1-x> );
or as
> P<x> := PowerSeriesRing(Integers());
> Z := LSeries(1, [0], 1, func<p,d|1-x+O(x^(d+1))> :
               Poles:=[1], Residues:=[-1], Sign:=1);
V2.28, 13 July 2023