I've coded up an implementation to calculate the riemann zeta function over the entire complex plane using math.js. It works very quickly for real numbers and uses a number of terms proportional to $\approx (1.3*\ln(d * 0.1)+ 0.9*|t|)$ where $d$ is the number of decimal places of accuracy and $t$ is the imaginary part of the input. I've implemented this in my small js library called special.js. Here is a description of the algorithm used:
Computation makes use of the function $\displaystyle d_k = n\sum_{j=k}^n \frac{(n+j-1)!4^j}{(n-j)!(2j)!}$ where $n$ is chosen arbitrarily making use of the precision and uses $\displaystyle\zeta(s) = \frac{1}{d_0(1-2^{1-s})}\sum_{k=1}^n \frac{(-1)^{k-1}d_k}{k^s}$ for $\Re(s) > 1$ and uses the functional equation $\displaystyle \zeta(s) = 2^s\pi^{s-1}\sin\bigg(\frac{\pi s}{2}\bigg)\Gamma(1-s)\zeta(1-s)$ where $\Gamma(s)$ is the gamma function to extend it to the entire complex plane.
The js code in math.js is as follows:
const math = require("mathjs")
function zeta(s, prec, only){
s = math.complex(s)
if (s.re == 0 && s.im == 0){
return -0.5
}
prec = prec == undefined ? 1e-3 : prec
let dec = -Math.round(Math.log(prec*0.1)/Math.log(10))
let n = Math.round(1.3*dec + 0.9*Math.abs(s.im))
n = Math.min(n, 60)
function d(k){
let S = 0
for (let j=k;j<=n;j++){
S += (math.factorial(n+j-1) * (4**j) / (math.factorial(n-j)*math.factorial(2*j) ))
}
return n*S
}
function f(s){
let c = math.divide(1,
math.multiply(d(0), math.subtract(1, math.pow(2, math.subtract(1, s)))))
let S = math.complex(0, 0)
for (let k=1;k<=n;k++){
S = S.add(
math.divide((-1)**(k-1) * d(k), math.pow(k, s))
)
}
return math.multiply(c, S)
}
if (s.re > 1 || s.re == 0 || only){
//console.log("Running "+ n +" iterations")
return f(s)
}
else{
let c = math.multiply(math.pow(2, s), math.pow(Math.PI, math.subtract(s, 1)))
c = math.multiply(c, (math.sin(math.multiply(Math.PI/2, s))))
c = math.multiply(c, math.gamma(math.subtract(1, s)))
//Recursion
return math.multiply(c, zeta(math.subtract(1, s), prec, true))
}
}
function benchmark(s, n){
let avg = 0
for (let i=0;i<n;i++){
let now = performance.now()
zeta(s, 0.0000001)
avg += performance.now() - now
}
return avg/n
}
console.log(benchmark(math.complex(1/2, 14.134725), 100)) //First zero of the zeta function
I'm not very experienced in node.js libraries and such so I hope that someone more experienced can add it to the library.
I've coded up an implementation to calculate the riemann zeta function over the entire complex plane using math.js. It works very quickly for real numbers and uses a number of terms proportional to$\approx (1.3*\ln(d * 0.1)+ 0.9*|t|)$ where $d$ is the number of decimal places of accuracy and $t$ is the imaginary part of the input. I've implemented this in my small js library called
special.js. Here is a description of the algorithm used:Computation makes use of the function$\displaystyle d_k = n\sum_{j=k}^n \frac{(n+j-1)!4^j}{(n-j)!(2j)!}$ where $n$ is chosen arbitrarily making use of the precision and uses $\displaystyle\zeta(s) = \frac{1}{d_0(1-2^{1-s})}\sum_{k=1}^n \frac{(-1)^{k-1}d_k}{k^s}$ for $\Re(s) > 1$ and uses the functional equation $\displaystyle \zeta(s) = 2^s\pi^{s-1}\sin\bigg(\frac{\pi s}{2}\bigg)\Gamma(1-s)\zeta(1-s)$ where $\Gamma(s)$ is the gamma function to extend it to the entire complex plane.
The js code in math.js is as follows:
I'm not very experienced in node.js libraries and such so I hope that someone more experienced can add it to the library.