|
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.
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.
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).
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.
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.
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.
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.
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).
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 [a 1, ..., a N].
> 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.
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);
[Next][Prev] [Right] [Left] [Up] [Index] [Root]
|