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.