// Formula for calculating the Riemann Zeta function. // // This follows the very efficient algorithm set out by P. Borwein in // "An Efficient Algorithm for the Riemann Zeta Function", Jan. 20, 1995. // // http://eprints.cecm.sfu.ca/archive/00000107/ // // or // https://vdoc.pub/download/an-efficient-algorithm-for-the-riemann-zeta-function-6p64dg2ligs0 // // This implements Algorithm 2 of the paper. // // As noted by Borwein, "These algorithms do not compete with the // Riemann-Siegel formula for computations concerning zeros on the critical // line (Im[s] = 1/2) where multiple low precision evaluations are required." // // This means that it'll work around the critical line, but there are known // faster algorithms if you just need low precision and only work around the // critical line. // // This is the prototype of the (not-yet-implemented) Riemann Zeta function // in Frink. // Calculate the value of the Riemann Zeta function at s // n is the approximate number of digits of accuracy. This automatically // sets n to a minimum of 30 because the algorithm does not converge accurately // with fewer terms. RiemannZeta[s, n=30] := { if n<30 n = 30 rnn = RiemannD[n] sum = 0 for k = 0 to n-1 sum = sum + (-1)^k (rnn@k - rnn@n)/(k+1)^s return sum * (-1/(rnn@n * (1 - 2^(1-s)))) } // Calculate an array of values for d_0 ... d_n // n is the approximate number of digits of precision in the result. // This array should be stored and re-used across calculations. RiemannD[n] := { ret = new array[n+1] sum = 0 for i = 0 to n { sum = sum + ((n+i-1)! 4^i)/((n-i)! (2i)!) ret@i = n * sum } return ret }