Is there any way to check for all roots in a range? Jens' findAllRoots function is pretty good, but runs at approx. 10% of roots missed when I ran a quick check on Zeta[1/2+I y]. Is there anything that will get a little closer to 100%?
2 Answers
I think doing this numerically you need to be really careful with numerical precision issues. This finds the first hundred or so roots, recursively searching between each pair of previously found roots.
Clear[rootsinrange];
rootsinrange[{a_, b_}] := rootsinrange[{a, b}] =
(p = Select[
Partition[ First@Cases[ Plot[ Re@Zeta[1/2 + I y] , {y, a, b},
PlotPoints -> 1000] , Line[x_] -> x, Infinity] , 2, 1] ,
#[[1, 2]] #[[2, 2]] <= 0 & ];
y /. FindRoot[ Re@Zeta[1/2 + I y] , Join[{y}, #[[All, 1]]]] & /@ p);
all = Sort[Join[ rootsinrange[{0, 100}], rootsinrange[{300, 310}] ]];
all = NestWhile[
Union[Flatten[ (Join[#, rootsinrange[{#[[1]], #[[2]]}] ] & /@
Partition[#, 2, 1] )],
SameTest -> (Abs[#1 - #2] < 10^-8 &)] & , all, #1 != #2 &, 2] ;
First find all roots of the real part, then select the roots where the imaginary part is also zero:
allz = Select[ all , Abs[ Im[ Zeta[1/2 + I #] ]] < 10^-8 &]
Length[allz]
143
Note the uncomfortably coarse tolerance (10^-8). If you tighten that you loose good roots and get a bunch of extras numercally close to each other.
I had to play with that tolerance to exactly get the same result as `ZetaZero':
Max[Abs[allz - Im[ZetaZero[Range[143]] - 1/2]]]
5.11932*10^-10
- 38,913
- 1
- 43
- 110
-
Does
Solve[Zeta[1/2 + I y] == 0 && 0 < Abs@y < 100, y, Complexes]give same result as your method? For numerical, one can always throwNon it with some precision value as needed? I did not compare if this gives same results as what you have. – Nasser Oct 20 '14 at 20:41 -
Solvegives the result that the roots are+/-Im[ZetaZero[i] - 1/2]for anyi>0(plus the trivial roots) .. at least as I read the question/comments he wants to find the roots without usingZetaZero– george2079 Oct 20 '14 at 20:57 -
@george2079 This is great! It is certainly much faster than
Reduce. I will continue to test it for some other functions & at greater heights - but looks really good so far :) – martin Oct 20 '14 at 21:50 -
@george2079 for what I'm after, in terms of speed / accuracy best compromise, your solution suits me best. Many thanks! :) – martin Oct 21 '14 at 11:06
You can use Reduce, as described here.
Generally, for this to work, you need to give bounds for the search domain, e.g.
Reduce[f[x] == 0 && -10 < x < 10, x]
for reals or
Reduce[f[z] == 0 && Abs[z] < 10, z]
for complex.
It will not be fast, but according to the blog post I linked, it is guaranteed to find all roots (if it returns a result).
- 234,956
- 30
- 623
- 1,263
-
-
-
@george2079 Yes, but why do you think that is a problem? When
Reducecan provide a closed form solution, it will. When it cannot, it will returnRootobjects. The point is that this method works in a surprisingly large number of cases, with many transcendental equations. It would likely still work ifReducedidn't know aboutZetaZero. – Szabolcs Oct 20 '14 at 20:47 -
just looking at the comments @matin maybe should clarify the question as he seems to be aware of
ZetaZeroand looking for an alternative for some reason. – george2079 Oct 20 '14 at 21:01 -
@Szabolcs for what I'm after, in terms of speed/accuracy compromise, george2079's solution suits me best, but your help here with
Reduceis good to know (especially if I get a more powerful computer!) - many thanks :) – martin Oct 21 '14 at 11:08
Zetathere isZetaZerofinding first10000000roots or if you want roots of e.g. the real part ofZetayou can useFindRootas described here When does the real part of Zeta vanish on the critical line? – Artes Oct 20 '14 at 16:33ZetaZero. Will give the FindRoot another go, but throws up losts of duplicates & some misses so far. – martin Oct 20 '14 at 16:48Solveworks also:Solve[Zeta[1/2 + I y] == 0 && -10 < Abs@y < 10, y, Complexes]gives{{y -> (5 I)/2}, {y -> (9 I)/2}, {y -> (13 I)/2}, {y -> (17 I)/2}}So doesNSolve– Nasser Oct 20 '14 at 20:20