# Finding zeros of zeta function.

I am trying to make the following code work.

t = var('t')
f = zeta(1/2+i*t).abs()
ff = fast_callable(f, vars=[t], domain=CDF)
print find_root(ff, 0, 40)


There are actually 6 roots between 0 and 40. But find_root could not find any of them. Is there any walkaround?

edit retag close merge delete

Sort by » oldest newest most voted

The probleme is the use of abs. Indeed, your function f will not change its sign, so that the zeroes are hard to find, especially, with the numerical noise. Here is how your function looks like (see this sample):

sage: plot(ff, 0, 40)


So, what you could do is to locate the zeroes of the real part of the function, not its absolute value:

sage: f = zeta(1/2+i*t).real()
sage: ff = fast_callable(f, vars=[t], domain=CDF)


As you can see, there are too many roots (basically twice as much as you want, see this sample):

sage: plot(ff, 0, 40)


So, to select the correct ones, let us also look at the imaginary part of the function (see this sample):

sage: g = zeta(1/2+i*t).imag()
sage: gg = fast_callable(g, vars=[t], domain=CDF)
sage: plot(ff, 0, 40) + plot(gg, 0, 40, color='red')


So, now you have to find the common zeroes. find_root only finds one root, so let us for exemple use the recursive algorithm described on this ask question, and look for the common roots of the real and the imaginary part of the function. The problem is that there are numerical approximations of the roots, so they might not exactly be equal:

sage: A = find_root_recursive(ff,0,40)
sage: B = find_root_recursive(gg,0.1,40)
sage: [a for a in A for b in B if a == b]
[30.424876125859512, 37.586178158825675]


So, we should add some tolerance:

sage: [a for a in A for b in B if abs(b-a)<0.00001]
[14.134725141735002,
25.010857580145707,
21.022039638771638,
30.424876125859512,
32.93506158773919,
37.586178158825675]


Here are the 6 zeroes you were looking for.

Note that if you want to go further, you will have to play with the tolerance in find_root_recursive since consecutive zeroes get closer and closer.

more

You may also install an optional package:

sage -i database_odlyzko_zeta


which allows to get a list of the first 2 millions zeros:

sage: zz = zeta_zeros()
sage: type(zz)
<type 'list'>
sage: len(zz)
2001052
sage: zz[:6]
[14.134725142,
21.022039639,
25.01085758,
30.424876126,
32.935061588,
37.586178159]

more