Where are the zeros of a slightly perturbed Riemann Zeta function?

277 Views Asked by At

We seek to understand the locations of the zeros when we introduce a minor perturbation to the Riemann Zeta function:

${\displaystyle \zeta (s)=\sum _{n=1}^{\infty }{\frac {1}{n^{s}}}={\frac {1}{1^{s}}}+{\frac {1}{2^{s}}}+{\frac {1}{3^{s}}}+{\frac {1}{4^{s}}}+\cdots}$

For instance, consider the following slightly perturbed Zeta function:

${\displaystyle N(s)={\frac {1}{1^{s}}}+{\frac {2}{2^{s}}}+{\frac {1}{3^{s}}}+{\frac {1}{4^{s}}}+\cdots}$

Where are its zeros located on the complex plane? (We can assume the Riemann Hypothesis is true.)

4

There are 4 best solutions below

0
On BEST ANSWER

Here is a graph showing the first 10 zeroes of the modified $\zeta$-function $$f(s) = \zeta(s) + \epsilon / 2^{s}\tag{1}$$ in the complex $s$-plane together with the original Riemann zeroes. The picture neatly shows how a specific zero (black) is shifted due to a positive (blue) and negative (red) perturbation.

enter image description here

A modified zero has been calculated with the Mathematica code shown below using 30 iterations of the Newton algorithm with the initial value equal to the corresponding Riemann zero. The imaginary parts of the Riemann zeroes were taken from https://www.lmfdb.org/zeros/zeta/, the real part is taken as $0.5$ following the Riemann hypothesis.

For those who have access to Mathematica here is the code:

(* The function zeroes230902 calculates the zeroes n1 through n2 *)
(* of a modified zeta function f(s,eps)=Zeta(s)+eps delta(s)     *)
(* using Newton iteration with iter steps                        *)
(* and initial values equal to the corresponding Riemann zero.   *)
(* The imaginary parts of the Riemannian zeroes,stored externally*)
(* in zr0,are taken from https://www.lmfdb.org/zeros/zeta/       *)
(**)
(* Example of the function call:                                 *)
(* zeroes230902[0.3,5,2,6,Function[s,1/2^s]]                     *)

zeroes230902[eps_, iter_, n1_, n2_, delta_] :=
 Module[{x, t, z, del, f, f1, zr},
  del[s_] = delta[s]; f[s_, epsilon_] = Zeta[s] + epsilon* del[s]; 
  f1[s_, epsilon_] = D[f[s, epsilon], s];
  zr = Take[zr0, {1, 50}];  (* sample of the first 50 Riemann zeroes *)
  x = Table[z[1] = N[1 + zr[[j]] I];
    t = Table[
      z[k + 1] = N[z[k] - f[z[k], eps]/f1[z[k], eps]], {k, 1, iter}];
    t[[-1]], {j, n1, n2}];
  x]

Example call

zeroes230902[0.0, 15, 3, 5, Function[s, 1/2^s]]
zeroes230902[+0.3, 15, 3, 5, Function[s, 1/2^s]]
zeroes230902[-0.3, 15, 3, 5, Function[s, 1/2^s]]

{0.5 + 25.0109 I, 0.5 + 30.4249 I, 0.5 + 32.9351 I}
{0.438434 + 24.8655 I, 0.520432 + 30.5937 I,  0.523301 + 32.7755 I}
{0.557216 + 25.1517 I, 0.4778 + 30.2692 I, 0.474581 + 33.0804 I}

Discussion

§1. Approximate shifted root position

Writing the approximate root $s$ of $f(s)=\zeta(s) + \epsilon \delta(s)$ as $s(s_0) =s_0 + \epsilon \eta(s0)$ where $s_0$ is the Riemann zero in question we obtain to first order in $\epsilon$

$$\eta(s_0) = - \frac{\delta(s_0)}{\zeta'(s_0)}\tag{2}$$

This is actually the first iteration of the Newton algorithm.

3
On

Broadly speaking, taking linear combinations of $L$-functions give functions that have many zeros near the half-line, but also with many zeros all over. There isn't a good way to find these zeros, but it's not very hard to simply go and compute some.

For the function $f(s) = \zeta(s) + \frac{1}{2^s}$, I computed a couple hundred zeros nearish the critical line. It would be possible to do this rigorously using Cauchy's residue formula, but I just used Newton's method on a mesh of points and removed duplicates.

The first (that I found --- this list is probably not complete) several zeros are at the bottom of this post.

As one can see, they appear somewhat random. There are some in the region of absolute convergence, for example $s_1 = 1.18155595111619 + 13.8549476070918i$. These are perhaps easier to verify, as elementary estimates show $\zeta(s_1) \approx 0.433 - 0.078i$ and $2^{-s_1} \approx -0.433 + 0.078i$.

 0.608530371934972 + 4.26404281725873*I,
 1.18155595111619 + 13.8549476070918*I, 
 0.261075254600588 + 24.5028774589355*I,
 0.686982196357885 + 21.6442678405853*I,
 0.571594889811657 + 32.2809480702920*I,
 0.561799649178136 + 31.1069189276823*I,
 1.01312826981529 + 40.9493043996571*I, 
 0.203247036583049 + 37.7669305594545*I,
 0.186720476429387 + 43.1268593041915*I,
 1.06217193214242 + 49.6288652866812*I, 
 0.154647361762731 + 48.2984359646153*I,
 0.280290010982236 + 52.8103229795903*I,
 0.328892676559822 + 56.6784515719099*I,
 1.07330622162077 + 59.3143586659668*I, 
 0.148567213296437 + 60.6583689501593*I,
 0.852060595678997 + 67.3648328248167*I,
 0.233749117077807 + 65.1791033894777*I,
 0.519567441565179 + 69.1985153917912*I,
 1.08936593388872 + 76.9852236089313*I, 
 0.289524729109100 + 72.0811381328665*I,
 0.221582207466821 + 76.0008445141189*I,
 0.300987803269673 + 79.1846342707407*I,
 0.674568639974302 + 85.0448504258809*I,
 0.785608699658067 + 87.1120055376591*I,
 0.268475682232423 + 82.9370204326388*I,
 0.231264557697083 + 88.7894192739031*I,      
 0.304547844294147 + 92.5719742617833*I,
 0.249756762588726 + 95.4100949549107*I, 
 1.08817834429472 + 95.0930248700267*I, 
 0.347904167782075 + 101.453461013395*I,
 0.343288657447096 + 98.7434579783956*I,
 0.607243131219802 + 104.995833748037*I,
 0.760594236525269 + 104.086748243230*I,
 0.297351145257549 + 107.157040613773*I,
 0.324203981537656 + 116.128146491521*I,
 0.678548857618410 + 114.053889595655*I,
 0.828118815715211 + 112.262665310805*I,
 0.193164111887456 + 110.980403788449*I,
 1.01999324921567 + 122.659106050461*I,
 0.255140693697753 + 124.164092823984*I,
 0.354403227545831 + 118.862047509191*I,
 0.406102087685723 + 121.711037835340*I,
 0.891034645359411 + 131.099003129259*I,
 0.345620089609479 + 127.493221027943*I,
 0.527445710540387 + 133.201657260850*I,
 0.350576787494291 + 129.832341026987*I,
 0.304781739406574 + 134.808085827953*I,
 0.827065612049055 + 140.337788997085*I,
 0.569158444824640 + 140.543492560166*I,
 0.354820706721776 + 143.022900523662*I,
 0.314393290186259 + 138.175819876305*I,
 0.320523916303474 + 145.976972479331*I,
 1.06983130596373 + 150.083689086408*I,
 0.507889147920485 + 147.664900282908*I,
 0.191154908041025 + 150.682864581192*I,

Edit to include code

The following is a basic implementation for this problem in the free CAS sagemath.

def f(s):
    return CC(zeta(s)) + CC(2**(-s))

def fprime(s):
    return CC(zetaderiv(1, s)) - CC(2**(CC(-s)) * CC(log(2)))

def newton(s0, iters=50, toofar=10, verbose=False):
    scurrent = s0
    snext = 0
    for _ in range(iters):
        if abs(scurrent - s0) > toofar:
            return None
        snext = scurrent - f(scurrent) / fprime(scurrent)
        if verbose:
            print(snext)
        scurrent = snext
    return scurrent

def isolate(cands, tolerance=1e-3):
    ret = []
    for cand in cands:
        if any(abs(cand - r) < tolerance for r in ret):
            continue
        ret.append(cand)
    return ret

def collect_zeros():
    cands = [newton(CC(0.5 + 1j * k)) for k in range(200)]
    cands = [cand for cand in cands if cand is not None]
    zeros = isolate(cands)
    zeros.sort(key = lambda z : z.imag())
    return zeros

I briefly describe this code. Newton's method takes the form of iterations

$$ z_{n+1} = z_n - \frac{f(z_n)}{f'(z_n)}. $$

The iterates $z_n$ will tend to a zero if the initial guess is close enough. The poorly named f(s) function is calculates $\zeta(s) + 2^{-s}$. (Actually, it asks PARI/GP to compute $\zeta(s)$ and adds $2^{-s}$ to it). I also hardcode in the derivative, using sage's zetaderiv (which actually calls mpmath's $\zeta'(s)$ evaluator) and a hardcoded derivative of $2^{-s}$.

An oddity here is that I put many things in CC(). In sage, this tells the computation to occur in double precision. Sage would rather try to keep things algebraically pure, which has a significant computational burden and is unnecessary here.

The function newton(s0, iters, toofar, verbose) is a function that performs iters many Newton iterations beginning with s0. In principle, iterations might find some far away zero. But I didn't want to deal with that, so if any iterate goes more than toofar away from s0, then I terminate the iteration and return None. (This is not great coding style). And because it is sometimes nice to see how things go, I also threw in a verbose flag, which just prints out iterates as they are computed.

Then I include two convenience functions. The function isolate(cands, tolerance) takes a list of potential zeros and reduces them so that no two zeros are within tolerance of each other. When using Newton's method on a mesh, you'll find the same zero repeatedly. I assumed that no two zeros will be within $0.001$ of each other --- at least, in the range I'm computing with. Direct inspection suggests this is true, but I note that it's not obviously true.

And the final convenience function is collect_zeros(), which runs Newton's method on a 1D mesh on the half-line up to $1/2 + 200i$. It removes duplicates (as described above) and sorts based on imaginary part. It is naive. On my machine, this ran in approximately 20 seconds.

With this short script, one can do

> zs = collect_zeros()   # took ~20s on my machine
> all(abs(f(z)) < 1e-12 for z in zs)
True
> zs[:20]
[0.261967395716187,
 0.608530371934972 + 4.26404281725873*I,
 1.18155595111619 + 13.8549476070918*I,
 0.686982196357885 + 21.6442678405853*I,
 0.261075254600588 + 24.5028774589355*I,
 0.561799649178136 + 31.1069189276823*I,
 0.571594889811657 + 32.2809480702920*I,
 0.203247036583049 + 37.7669305594545*I,
 1.01312826981529 + 40.9493043996571*I,
 0.186720476429387 + 43.1268593041915*I,
 0.154647361762731 + 48.2984359646153*I,
 1.06217193214242 + 49.6288652866812*I,
 0.280290010982236 + 52.8103229795903*I,
 0.328892676559822 + 56.6784515719099*I,
 1.07330622162077 + 59.3143586659668*I,
 0.148567213296437 + 60.6583689501593*I,
 0.233749117077807 + 65.1791033894777*I,
 0.852060595678997 + 67.3648328248167*I,
 0.519567441565179 + 69.1985153917912*I,
 0.289524729109100 + 72.0811381328665*I]

It should not be hard to improve this code, or to modify it for similar situations.

0
On

It might be of interest to mention the Bombieri-Hejhal result on the (off-the-line) zeros of linear combinations of two $L$-functions that individually have the same functional equation... namely, the Hecke L-functions attached to the trivial and non-trivial class-group of $\mathbb Q(\sqrt{-5})$: On the distribution of zeros of linear combinations of Euler products}, Duke Math. J. 80 (1995), 821-862.

In that case (unsurprisingly), there are many off-line zeros... but/and something non-trivial can be said about their distributions.

4
On

(* Mathematica *)

n = 20; (* set n = 30 for better precision *)
s = 1 + 14*I; (* change the number s=1+14*I to get another zero closest to it *)
s + 1/n + 
  1/(1 - Sum[(-1)^(k - 1)*
        Binomial[n - 1, 
          k - 1]/(HarmonicNumber[10^10000, s + k/n] + 
           1/2^(s + k/n)), {k, 1, n}]/
      Sum[(-1)^(k - 1)*
        Binomial[n - 1, 
          k - 1]/(HarmonicNumber[10^10000, s + k/n + 1/n] + 
           1/2^(s + k/n + 1/n)), {k, 1, n}]);
N[%, 15]

Output: 1.18155595111619 + 13.85494760709183 I

Which matches the third zero in the list in the answer by davidlowryduda