解析方法数质数:从入门到入土(下)

\newcommand{\tO}{\widetilde O} \newcommand{\hphi}{\widehat \phi} \newcommand{\hPhi}{\widehat \Phi} \newcommand{\sinc}{\text{sinc}}上次我们讲了 [LO],[Galway] 和 [Platt] 的大致思路,似乎一切都已经明了,只剩下最后一个难点了:ζ\zeta 函数怎么求?这里我们就来介绍一下我 survey 到的几种求 ζ(s)\zeta(s) 的方法。

这里我们先约定:文中的所有 σ\sigma 可以被替换为 (s)\Re(s)tt 可以被替换为 (s)\Im(s)

我们再对 ζ(s)\zeta(s) 的需求细分一下:在 [LO] 和 [Galway] 中,我们真的需要 ζ(s)\zeta(s) 的值,因为最后的积分需要,而且这里的 ss 还不满足 σ=12\sigma = \frac{1}{2}。而在 [Platt] 中,我们并不关心 ζ(s)\zeta(s) 的值,我们只关心 ζ(s)\zeta(s) 的非平凡零点在哪里。

想必大家都听说过 Riemann hypothesis 的名字。它是数学界最著名的 hypothesis 之一,说的就是:ζ(s)\zeta(s) 的所有非平凡零点均有 σ=12\sigma = \frac{1}{2}。于是大家便称 σ=12\sigma = \frac{1}{2} 这条线为 critical line。我们在接下来的分析中也会经常看到 critical line 上的 ss 会有特殊的性质。

Euler-Maclaurin 公式

TL;DR:用 \eqrefeq:eulermaclaurinerrorterm\eqref{eq:euler-maclaurin-error-term} 来计算一个合适的 mm,然后用 \eqrefeq:zetaeulermaclaurin\eqref{eq:zeta-euler-maclaurin} 来计算 ζ(s)\zeta(s)

当然最古老是还是 Euler-Maclaurin 公式。在二十世纪三十年代之前一直都是用这个公式来计算 ζ(s)\zeta(s) 的。我们再来复习一下 Euler-Maclaurin 公式:

[Euler-Maclaurin Formula]a<ba< b 为两自然数,对于任意正整数 mmff[a,b][a, b] 上连续,则有

abf(x)dx=i=abf(x)12(f(a)+f(b))k=1m1B2k(2k)!(f(2k1)(b)f(2k1)(a))+R2m,\int_a^b f(x) \d x = \sum_{i=a}^b f(x) - \frac{1}{2}(f(a) + f(b)) - \sum_{k=1}^{m-1} \frac{B_{2k}}{(2k)!}(f^{(2k-1)}(b) - f^{(2k-1)}(a)) + R_{2m},

其中 B2kB_{2k} 为 Bernoulli 数,R2mR_{2m} 为余项。

我们不妨把取 f(x)=xsf(x) = x^{-s},有 f(2k1)(x)=x12ksj=02k2(s+j)f^{(2k-1)}(x) = -x^{1-2k-s} \prod\limits_{j=0}^{2k-2} (s + j),带入即有

abxsdx=i=abxsas+bs2+k=1m1B2k(2k)!(b12ksa12ks)j=02k2(s+j)+R2m,\int_a^b x^{-s} \d x = \sum_{i=a}^b x^{-s} - \frac{a^{-s} + b^{-s}}{2} + \sum_{k=1}^{m-1} \frac{B_{2k}}{(2k)!} \left( b^{1-2k - s} - a^{1-2k - s} \right) \prod_{j=0}^{2k-2} (s+j) + R_{2m},

然后我们取 bb 的极限到 \infty,有

ζ(s)=i=1xs=i=1a1xs+axsds+as2+k=1m1B2k(2k)!a12ksj=02k2(s+j)+R2m.\labeleq:zetaeulermaclaurin\begin{equation} \zeta(s) = \sum_{i=1}^\infty x^{-s} = \sum_{i=1}^{a-1} x^{-s} + \int_a^\infty x^{-s} \d s + \frac{a^{-s}}{2} + \sum_{k=1}^{m-1} \frac{B_{2k}}{(2k)!} a^{1-2k-s} \prod_{j=0}^{2k-2} (s+j) + R_{2m}. \label{eq:zeta-euler-maclaurin} \end{equation}

中间这个积分非常显然,我就懒得化开了。不妨令 Ta,k(s):=B2k(2k)!a12ksj=02k2(s+j)T_{a, k}(s) := \frac{B_{2k}}{(2k)!} a^{1-2k-s} \prod\limits_{j=0}^{2k-2} (s+j),在 σ>2m+1\sigma > -2m + 1 的情况下,[Eq 1.3, OS] 给了 R2mR_{2m} 的一个 bound:

R2ms+2m1σ+2m1Ta,m(s).\labeleq:eulermaclaurinerrorterm\begin{equation} |R_{2m}| \leq \left| \frac{s + 2m - 1}{\sigma + 2m - 1} T_{a, m}(s) \right|. \label{eq:euler-maclaurin-error-term} \end{equation}

故我们需要选择合理的 mmaa 使得 R2mR_{2m} 小。当 (s)=12\Re(s) = \frac{1}{2} 时,可以选择 at/(2π)a \approx t / (2\pi)mnm \approx \sqrt{n},不过我也没算这样是否合理……但是从这里可以看出:Euler-Maclaurin 公式的复杂度是 \tO(t)\tO(t) 的,在 tt 大的情况非常菜,所以我们还需要改进……

Riemann-Siegel 公式

注意到我之前说二十世纪三十年代之前都是用 Euler-Maclaurin 公式来计算 ζ(s)\zeta(s) 的,那么是什么打破了这一局面呢?没错就是 Siegel 在整理 Riemann 在 1850 年代的手稿时发现了这个公式,于是被称为 Riemann-Siegel 公式。

首先我们来介绍一个 Riemann-Siegel 公式。它有很多变种,我们先说其中一个:[Eq 7.2, Galway], [Eq 1.1, de Reyna] 对于任意 ss,有

ζ(s)=R(s)+χ(s)R(1sˉ),R(s):=01zseiπz2eiπzeiπzdz,\zeta(s) = \mathcal{R}(s) + \chi(s) \overline{\mathcal{R}(1 - \bar s)}, \quad \mathcal{R}(s) := \int\limits_{0 \swarrow 1} \frac{z^{-s} e^{i \pi z^2}}{e^{i\pi z} - e^{-i\pi z}} \d z,

其中 010 \swarrow 1 描述 12eiπ/4α\frac{1}{2} - e^{i \pi /4} \alpha 这条路径,<α<-\infty < \alpha < \infty, χ(s)\chi(s)

χ(s):=πs1/2Γ((1s)/2)Γ(s/2).\chi(s) := \pi^{s - 1/2} \frac{\Gamma((1 - s) / 2)}{\Gamma(s / 2)}.

注意到 f(z;s):=zseiπz2eiπzeiπzf(z; s) := \frac{z^{-s} e^{i \pi z^2}}{e^{i \pi z} - e^{-i \pi z}} 是一个亚纯函数,极点为所有整数,且在正整数 nn 上的留数为:

Res(f;n)=limznf(z;s)(zn)=zseiπz2limznzneiπzeiπz=zs2πi.\text{Res}(f; n) = \lim_{z \to n} f(z; s) (z - n) = z^{-s} e^{i \pi z^2} \lim_{z \to n} \frac{z - n}{e^{i \pi z} - e^{-i \pi z}} = \frac{z^{-s}}{2 \pi i}.

故我们可以把 010 \swarrow 1 这条线移到 NN+1N \swarrow N+1 ,由留数定理可得:

R(s)=01f(z;s)dz=2πin=1NRes(f;n)+NN+1f(z;s)dz=n=1Nns+NN+1f(z;s)dz.\mathcal{R}(s) = \int\limits_{0 \swarrow 1} f(z; s) \d z = 2 \pi i \sum_{n=1}^N \text{Res}(f; n) + \int\limits_{N \swarrow N+1} f(z; s) \d z = \sum_{n=1}^N n^{-s} + \int\limits_{N \swarrow N+1} f(z; s) \d z.

对于任意非负整数 N,MN, M,均有

ζ(s)=n=1Nns+χ(s)n=1Mns1+RN,M(s).\labeleq:RS1\begin{equation} \zeta(s) = \sum_{n=1}^N n^{-s} + \chi(s) \sum_{n=1}^M n^{s-1} + R_{N, M}(s). \label{eq:RS-1} \end{equation}

其中 RN,MR_{N, M} 为余项。我们可以通过分析余项来分析 \eqrefeq:RS1\eqref{eq:RS-1} 的准确度。

[Gabcke] 在 Critical Line 上的 ζ(s)\zeta(s) 算法

TL;DR:用 \eqrefeq:RSzeta\eqref{eq:RS-zeta} 来计算 θ(t)\theta(t),用 \eqrefeq:gabcke\eqref{eq:gabcke} 来计算 Z(t)Z(t),用 \eqrefeq:gabckeerrorterm\eqref{eq:gabcke-error-term} 计算在何处截断 \eqrefeq:gabcke\eqref{eq:gabcke} 里的级数,最后用 \eqrefeq:RSzetaZtheta\eqref{eq:RS-zeta-Z-theta} 来计算 ζ(1/2+it)\zeta(1/2+it)

我们先写出一个关于 ζ(s)\zeta(s) 的美妙的对称性质:

πs/2Γ(s/2)ζ(s)=π(1s)/2Γ((1s)/2)ζ(1s).\labeleq:functional\begin{equation} \pi^{-s/2} \Gamma(s/2) \zeta(s) = \pi^{-(1-s) / 2} \Gamma((1-s)/2) \zeta(1 - s). \label{eq:functional} \end{equation}

这个对称性揭示了 ξ(s):=πs/2Γ(s/2)ζ(s)\xi(s) := \pi^{-s/2} \Gamma(s/2) \zeta(s) 关于 critical line 是对称的,这也就意味着:对于 critical line 上的 ss,有

ξ(s)=ξ(sˉ)=ξ(1s)=ξ(s),\overline{\xi(s)} = \xi(\bar s) = \xi(1 - s) = \xi(s),

ξ(s)\xi(s) 一定是实数。所以 critical line 上的 ssarg(πs/2Γ(s/2))=argζ(s)\arg (\pi^{-s/2} \Gamma(s/2)) = -\arg \zeta(s),从而我们可以定义 Riemann-Siegel θ\theta 函数:

θ(t):=arg(π(1/2+it)/2Γ((1/2+it)/2))=arg(Γ(1/2+it2))12tlogπ,\theta(t) := \arg(\pi^{-(1/2+it)/2} \Gamma((1/2+it)/2)) = \arg \left(\Gamma\left( \frac{1/2 + it}{2} \right) \right) - \frac{1}{2} t \log \pi,

来描述 ζ(s)\zeta(s) 的幅角(的相反数),并以此定义 Riemann-Siegel Z 函数

Z(t):=eiθ(t)ζ(1/2+it).\labeleq:RSzetaZtheta\begin{equation} Z(t) := e^{i \theta(t)} \zeta\left( 1/2+it \right). \label{eq:RS-zeta-Z-theta} \end{equation}

根据前文所述,我们可以知道 Z(t)Z(t) 一定是实数。Z(t)Z(t) 在研究 ζ(s)\zeta(s) 在critical line 上的零点是特别有用,因为 Z(t)=ζ(1/2+it)|Z(t)| = |\zeta(1/2+it)|θ(t)\theta(t) 和前文定义的 χ(s)\chi(s) 有紧密联系:对 \eqrefeq:functional\eqref{eq:functional} 稍做移项,对于 critical line 上的 ss

χ(s)=ζ(s)ζ(1s)=Z(t)exp(iθ(t))Z(t)exp(iθ(t))=exp(2iθ(t)).\chi(s) = \frac{\zeta(s)}{\zeta(1 - s)} = \frac{|Z(t)| \exp(-i \theta(t))}{|Z(-t)| \exp(i\theta(t))} = \exp(-2i \theta(t)).

[Gabcke] 给出了 Z(t)Z(t) 的 Riemann-Siegel 公式:(感受一下即可,背不下来的……劝退开始

[Theorem 2.1.1, Theorem 2.1.6, Gabcke]

Z(t)=2n=1Ncos(θ(t)tlogn)n1/2+(1)(N1)an=0Cn(z)an,\labeleq:gabcke\begin{equation} Z(t) = 2 \sum_{n=1}^N \cos(\theta(t) - t \log n) n^{-1/2} + \frac{(-1)^{(N-1)}}{\sqrt{a}} \sum_{n=0}^\infty \frac{C_n(z)}{a^n}, \label{eq:gabcke} \end{equation}

其中 a:=t2πa := \sqrt{\frac{t}{2\pi}}N:=aN := \lfloor a \rfloorz:=12(aN)z := 1 - 2(a - N)

Cn(z):=122nk=03n/4dk(n)π2n2k(3n4k)!F(3n4k)(z),C_n(z) := \frac{1}{2^{2n}} \sum_{k=0}^{\lfloor 3n/4 \rfloor} \frac{d^{(n)}_k}{\pi^{2n - 2k} (3n - 4k)!} F^{(3n-4k)} (z),

再其中有

F(z):=cosπ2(z2+34)cosπz,F(z):=\frac{\cos \frac{\pi}{2}\left(z^{2}+\frac{3}{4}\right)}{\cos \pi z},

以及

dk(n+1)=(3n+14k)(3n+24k)dk(n)+dk1(n)n0 and 0k<3(n+1)4,dk(n)=0k<0 or k>3n4,d3n(4n)=λnn0,\begin{aligned} d_{k}^{(n+1)}& =(3 n+1-4 k)(3 n+2-4 k) d_{k}^{(n)}+d_{k-1}^{(n)} & & n \geq 0 \text{ and }0 \leq k<\frac{3(n+1)}{4},\\ d_{k}^{(n)}& =0 && k<0 \text { or } k>\frac{3 n}{4},\\ d_{3 n}^{(4 n)}& =\lambda_{n} && n \geq 0, \end{aligned}

以及

λ0=1,λn+1=1n+1k=0n24k+1E2k+2λnk(n0).\begin{aligned} \lambda_{0} &=1, \\ \lambda_{n+1} &= \frac{1}{n+1}\sum_{k=0}^{n} 2^{4 k+1}\left|E_{2 k+2}\right| \lambda_{n-k} & (n \geq 0). \end{aligned}

以及 EkE_{k} 为 Euler 数。

(此处给 MathPix 打个广告,五毛不谢。)

当然这里的 nn 取到无穷大上去了,所以我们需要截断。截断误差也由 [Gabcke] 给出:

[Theorem 3.2.2, Gabcke] 定义

RK(t):=1aK+1Cn(z)an,\labeleq:gabckeerrorterm\begin{equation} R_K(t) := \frac{1}{\sqrt{a}} \sum_{K+1}^{\infty} \frac{C_n(z)}{a^n}, \label{eq:gabcke-error-term} \end{equation}

t200t \geq 200 时,有

R0(t)<0.127t3/4,R5(t)<0.061t13/4,R1(t)<0.053t5/4,R6(t)<0.661t15/4,R2(t)<0.011t7/4,R7(t)<9.2t17/4,R3(t)<0.031t9/4,R8(t)<130t19/4,R4(t)<0.017t11/4,R9(t)<1837t21/4.\begin{array}{ll} \left|R_{0}(t)\right|<0.127 t^{-3 / 4}, & \left|R_{5}(t)\right|<0.061 t^{-13 / 4}, \\ \left|R_{1}(t)\right|<0.053 t^{-5 / 4}, & \left|R_{6}(t)\right|<0.661 t^{-15 / 4}, \\ \left|R_{2}(t)\right|<0.011 t^{-7 / 4}, & \left|R_{7}(t)\right|<9.2 t^{-17 / 4}, \\ \left|R_{3}(t)\right|<0.031 t^{-9 / 4}, & \left|R_{8}(t)\right|<130 t^{-19 / 4}, \\ \left|R_{4}(t)\right|<0.017 t^{-11 / 4}, & \left|R_{9}(t)\right|<1837 t^{-21 / 4}. \\ \end{array}

这货真是太复杂了,看得我脑袋疼……原文还是德语,我就只能看懂公式……(尽管如此,还是比 David Platt 的 paper 容易理解。)

(劝退结束)

可以注意到截断误差 RK(t)R_K(t) 对于小的 tt 不太友好,所以对于小的 tt 还得靠 Euler-Maclaurin……[LO] 里也注意到了这里,但是问题不大,因为要求 π(x)\pi(x) 的话,对于 t<x1/4t < x^{1/4}tt 我们只会 evaluate \tO(n1/4)\tO(n^{1/4}) 次,所以对于这些 tt 用 Euler-Maclaurin ,复杂度也是 \tO(n1/2)\tO(n^{1/2}),不影响整体复杂度。

[Gacbke] 的算法复杂度显然是 \tO(t)\tO(\sqrt{t}) 的,被第一项给 dominate 了。之后我们会讨论如何优化掉这一项。这里我们只要注意到 cos(θ(t)tlogn)n1/2=(eiθ(t)n1/2it)\cos(\theta(t) - t \log n) n^{-1/2} = \Re(e^{i \theta(t)} n^{-1/2-it}) ,所以这一项本质上还是在求 n=1Nns\sum\limits_{n=1}^N n^{-s}

说到具体实现的话。这个定理可以说非常简单明了清晰易懂了,可能最大的问题是要求一个函数的高阶导数。一个方法是手动展开,反正只需要常数项,另一个方法是手写符号计算,大炮打蚊子,还可以用维护幂级数的加减乘除以及 apply 上一个函数(反正只需要 apply 上一个 cos 就行了),应该是常数最小的方法之一了。

这里我们主要是求 Z(t)Z(t) ,因为 critical line 上基本上只关心零点,所以 Z(t)Z(t) 就足够了。当然你要是真的想求 ζ(s)\zeta(s) 也是可以的,[de Reyna] 做了和 [Gabcke] 类似的分析,连公式都是差不多的,我就懒得再抄一遍了,反正也没人看 →_→ 有人还实现了 de Reyna 的算法。另一种方法是由 ζ(s)=eiθ(t)Z(t)\zeta(s) = e^{-i\theta(t)} Z(t),所以我们还需要 θ(t)\theta(t) 的逼近。有了 Stirling 公式,θ(t)\theta(t) 的近似非常简单:

[Eq 2, Brent]

θ(t)=t2logt2πeπ8+j=1(1212j)B2j4j(2j1)t2j1.\labeleq:RSzeta\begin{equation} \theta(t) = \frac{t}{2} \log \frac{t}{ 2 \pi e} - \frac{\pi}{8} + \sum_{j=1}^\infty \frac{(1 - 2^{1 - 2j})|B_{2j}|}{4j(2j-1)t^{2j-1}}. \label{eq:RS-zeta} \end{equation}

[Galway] 的 ζ(s)\zeta(s) 算法

TL;DR 那你就别读了 →_→

[Galway] 的 ζ(s)\zeta(s) 算法比较 general ,可以对不在 critical line 上的 ss 也求值。

……我懒得写 argument 了,直接上结果:

[Theorem 7.3, Galway]H(z):=(1e2iπz)1H(z) := (1 - e^{2 i \pi z})^{-1}z1:=N+12αeiπ/4z_1 := N + \frac{1}{2} - \alpha e^{i\pi/4}NN+1N \swarrow N+1 上任意一点,hh 为任意复数满足 hh=eiπ/4\frac{h}{|h|} = -e^{i \pi /4},对于任意 0<NLR<NR0 < N_L \leq R < N_R,有

R(s)=n=1Nns+hm=0Mf(z1+mh;s)n=NLNnsH(nz1h)+n=N+1NRnsH(z1nh)+EΣ+Ef,\labeleq:galwayR\begin{equation} \mathcal{R}(s) = \sum_{n=1}^N n^{-s} + h \sum_{m=0}^M f(z_1 + mh; s) - \sum_{n=N_L}^N n^{-s} H\left( \frac{n - z_1}{h} \right) + \sum_{n = N+1}^{N_R} n^{-s} H\left( \frac{z_1 - n}{h} \right) + \mathcal{E}_\Sigma + \mathcal{E}_f, \label{eq:galway-R} \end{equation}

其中 EΣ\mathcal{E}_\SigmaEf\mathcal{E}_f 为余项,依赖于 h,N,NL,NR,Mh, N, N_L, N_R, M 的取值。

后面的分析给了如下算法:

[Section 7.4, Galway]

  1. 计算 zs:=s/(2πi)z_s := \sqrt{s / (2 \pi i)},取 N=zszsN = \lfloor \Re z_s - \Im z_s \rfloor
  2. 解出最大的 α1\alpha_1,使得 f(z1;s)ϵ|f(z_1; s)| \le \epsilonα1>0\alpha_1 > 0,取 z1=N+12+α1eiπ/4z_1 = N + \frac{1}{2} + \alpha_1 e^{i \pi /4}
  3. 解出最大的 α2\alpha_2,使得 f(z2;s)ϵ|f(z_2; s)| \le \epsilonα2>0\alpha_2 > 0,取 z2=N+12α2eiπ/4z_2 = N + \frac{1}{2} - \alpha_2 e^{i \pi /4}
  4. 枚举 MM,使得:
    1. h=(z2z1)/Mh = (z_2 - z_1) / M
    2. 计算 zL:=(2h)2+s/(2πi)+(2h)1z_L := \sqrt{(2h)^{-2} + s/(2\pi i)} + (2h)^{-1},取 NL=zLzLN_L = \lceil \Re z_L - \Im z_L\rceil
    3. 计算 zR:=(2h)2+s/(2πi)(2h)1z_R := \sqrt{(2h)^{-2} + s/(2\pi i)} - (2h)^{-1},取 NR=zRzRN_R = \lfloor \Re z_R - \Im z_R \rfloor
    4. 计算 Ef\mathcal{E}_f 的上界:令 g(z;s):=zseiπz2g(z; s) := z^{-s} e^{i\pi z^2},有 Efg(zL;s)e2iπ(zLz1)/h+g(zR;s)e2iπ(zRz1)/h.\left|\mathcal{E}_{f}\right| \ll\left|g\left(z_{\mathcal{L}} ; s\right) e^{-2 i \pi\left(z_{\mathcal{L}}-z_{1}\right) / h}\right|+\left|g\left(z_{\mathcal{R}} ; s\right) e^{2 i \pi\left(z_{\mathcal{R}}-z_{1}\right) / h}\right| .
    5. 找最小的正整数 MM 使得 Efϵ|\mathcal{E}_f| \leq \epsilon
  5. 用以上过程找到的 N,z1,M,h,NL,NRN, z_1, M, h, N_L, N_R 来计算 \eqrefeq:galwayR\eqref{eq:galway-R}

[Galway] 没有给出一个 explicit error bound。他只在 [Section 7.7, Galway] 中,给了一个 asympototic error bound:

[Section 7.7, Galway]

Ef=O(f(z1;s)+f(z2;s)),EΣ=O(g(zL;s)e2iπ(zLz1)/h+g(zR;s)e2iπ(zRz1)/h).\begin{aligned} |\mathcal{E}_f| & = O(|f(z_1; s)| + |f(z_2; s)|),\\ |\mathcal{E}_\Sigma| & = O(\left|g\left(z_{\mathcal{L}} ; s\right) e^{-2 i \pi\left(z_{\mathcal{L}}-z_{1}\right) / h}\right|+\left|g\left(z_{\mathcal{R}} ; s\right) e^{2 i \pi\left(z_{\mathcal{R}}-z_{1}\right) / h}\right| ). \end{aligned}

所以我也给不出分析 233333

在第 2 步和第三步涉及到最大化一个目标函数。在我实验中,这个函数几乎是单调的,所以二分一下就行了。

复杂度的话,明显可以看到是 \tO(N+M+NRNL)\tO(N + M + N_R - N_L)。显然 N=\tO(t1/2)N = \tO(t^{1/2})。[Section 7.6, Galway] 说要想做到 ϵ\epsilon 近似的话, M=\tO(ln3/2ϵ)M = \tO(\ln^{3/2} \epsilon),而实验证明 NRNLN_R - N_LMM dominate 了,所以复杂度就是 \tO(t1/2)\tO(t^{1/2}),而且瓶颈也在 \eqrefeq:galwayR\eqref{eq:galway-R} 第一项,和 Riemann-Siegel 公式一样。在下一大节里,我们讲讨论如何优化 n=1Nns\sum\limits_{n=1}^N n^{-s}

[Zetafast]

这是我在网上搜到的一篇 paper,方法似乎和 Riemann-Siegel 公式不同,但是我没仔细看了。另外我始终觉得他的复杂度估的不对:D(N,s)D(N, s) 里面需要求 λvN\lambda v NQ(v,)Q(v, \cdot),如果暴力求 Q(v,)Q(v, \cdot) 的话,总复杂度就变成 O(λv2N)=O(vvτ)O(\lambda v^2 N) = O(v \sqrt{v \tau}) 而不是 claim 的 O(vt)O(\sqrt{vt})。作者 Kurt Fischer 我也搜不到人,但是 arxiv 提供的源代码里,这人自称是日本津山工业高等专门学校的。而这 paper 质量也还行,不像是出自民科之手。这里有 pari/gp 的实现。

ζ(s)\zeta(s) 预处理快速求值

到这里,用 Riemann-Siegel 公式,即使没有预处理,我们也可以得到一个 \tO(x3/5)\tO(x^{3/5}) 的算法来求 π(x)\pi(x):只要好好 balance 一下暴力和积分的复杂度就行了。例如我们用 [Galway] 的思路,取 λ=\tO(x2/5)\lambda = \tO(x^{-2/5}),这样积分上限 T=\tO(x2/5)T =\tO(x^{2/5}),每次用 \tO(x1/5)\tO(x^{-1/5}) 的时间求一次 ζ(s)\zeta(s) ,整体复杂度就是 \tO(3/5)\tO(^{3/5})。但是作为 bibi 选手,我们怎么能停在这里呢!反正都是理性愉悦,不如将嘴巴精神贯彻到底!

前文提到的 [Gabcke] 和 [Galway] 都是基于 Riemann-Siegel 公式,复杂度为 \tO(t1/2)\tO(t^{1/2}),且瓶颈都是在求 F(t;N):=n=1Nn(σ+it)F(t; N) :=\sum\limits_{n=1}^N n^{-(\sigma + it)} 这一项,这里的 σ\sigma 是固定的。瓶颈之外,两者算法都是 polylogϵ1\text{poly}\log \epsilon^{-1} 级的。这里我们就来介绍一下如何通过预处理来快速求 F(t;N)F(t; N)。为了表达简单,接下来我就省略 F(t;N)F(t; N) 里的 NN 了。

我 survey 到的算法均和 [OS] 类似,里面的 O 是之前提到的 A.M. Odlyzko,S 是 Schönhage,他提出的 Schönhage-Strassen 算法已经被 GMP 实现出来了。这类算法的思路为:我们希望在 \tO(N)\tO(N) 的时间内算出 F(t0),F(t0+δ),,F(t0+Mδ)F(t_0), F(t_0 + \delta), \dots, F(t_0 + M \delta),其中 M,δM, \delta 是两个我们可以控制的参数,然后再设计不同的算法用预处理的 FF 快速计算满足 t0tt0+Mδt_0 \leq t \leq t_0 + M \delta 的任何一个 F(t)F(t)。所以我们会有两部分:一部分如何预处理,一部分如何在线回答。

[FKBJ] 的预处理

TD; DR: 找到一个次数合适的多项式 P(t)P(t) 来逼近 eite^{it} ,使得 \eqrefeq:polyapproxerr\eqref{eq:poly-approx-err} 不超过 ϵ\epsilon。然后用 \eqrefeq:fftf\eqref{eq:fft-f} 计算 f(x;k)f(x; k) ,再用快速 Fourier 变换计算 f^(x;k)\hat f(x; k),最后通过 \eqrefeq:finalG\eqref{eq:final-G} 来计算所有的 G(t)G(t)

他们号称是对 [Odlyzko] 的改进。我们考虑一个更 general 的问题:给定复数列 a1,,Na_{1, \dots, N} 和实数列 γ1,,N\gamma_{1, \dots, N},我们希望求对 [T,T][-T, T] 里的所有整数 tt 同时求

G(t):=n=1Naneiγnt.G(t) := \sum_{n=1}^N a_n e^{i \gamma_n t}.

an=n(σ+it0),γn=logna_n = n^{-(\sigma + i t_0)}, \gamma_n = -\log n,这时的 G(t)G(t) 就是我们的目标 F(t)F(t) 了。

首先,我们令 R=2r>TR = 2^r > T 为最小的大于 TT 的 2 的幂,于是对于任意 γn\gamma_n,都都可以找到一个 δn=γn2πdnR\delta_n = \gamma_n - \frac{2 \pi d_n}{R}δnπR|\delta_n| \leq \frac{\pi}{R}dnd_n 为整数。然后,我们可以找到一个 KK 次多项式 P(t)=k=0KcktkP(t) = \sum\limits_{k=0}^K c_k t^k 来在 [πTR,πTR]\left[\frac{-\pi T}{R}, \frac{\pi T}{R} \right] 上逼近 eite^{it}

于是我们有

G(t)=n=1Naneiγnt=n=1Nane2πidnt/R+iδnt=n=1Nane2πidnt/RP(δnt)+E,G(t) = \sum_{n=1}^N a_n e^{i \gamma_n t} = \sum_{n=1}^N a_n e^{2\pi i d_n t/R + i\delta_n t} = \sum_{n=1}^N a_n e^{2 \pi i d_n t / R} P(\delta_n t) + \mathcal{E},

其中 E\mathcal{E} 为用 P(t)P(t) 近似 eite^{it} 带来的误差。

继续展开 P(δnt)P(\delta_n t)

G(t)=k=0Kcktkn=1N(anδnk)e2πidnt/R+E.G(t) = \sum_{k=0}^K c_k t^k \sum_{n=1}^N (a_n \delta_n^k) e^{2 \pi i d_n t/R} + \mathcal{E}.

我们惊奇的发现,里面这个 n=1N\sum\limits_{n=1}^N 长得和 Fourier 变换好像……不妨令

f(x;k):=n[N]:dnxmodRanδnk,f^(x;k):=x=0R1f(x;k)e2πix/R,\labeleq:fftf\begin{equation} f(x; k) := \sum_{n \in [N]: d_n \equiv x \bmod{R}} a_n \delta^k_n, \qquad \hat f(x; k) := \sum_{x=0}^{R-1} f(x; k) e^{2 \pi i x/R}, \label{eq:fft-f} \end{equation}

那不就 f^\hat fff 的离散 Fourier 变换嘛……

于是有

G(t)=k=0Kcktkf^(x;k)+E.\labeleq:finalG\begin{equation} G(t) = \sum_{k=0}^K c_k t^k \hat f(x; k) + \mathcal{E}. \label{eq:final-G} \end{equation}

误差分析的话:这个比较简单,我上我也行,

EEe=i=1NanmaxtπT/ReitP(t),\labeleq:polyapproxerr\begin{equation} |\mathcal{E}| \leq \mathcal{E}_{e} = \sum_{i=1}^N |a_n| \max_{|t| \leq \pi T/R} |e^{it} - P(t)|, \label{eq:poly-approx-err} \end{equation}

所以只要 P(t)P(t)eite^{it} 足够靠近,问题就不大。用 eite^{it} 的泰勒展开,只要 O(logϵ1)O(\log \epsilon^{-1}) 项就能逼近到 Eϵ|\mathcal{E}| \leq \epsilon

不难看出,预处理复杂度是 \tO(N)\tO(N) 的。

[OS] 的在线计算

懒得看了……有兴趣的朋友也可以参考 [Section 2.3, Gourdon]。我在这里只是道听途说的参考 [Odlyzko]。

[OS] 的思路是:我仍然预处理出一个格点上的 F(t;N)F(t; N)。不仅如此,我还预处理出格点上的 F(t;N)F(t; N) 上的高阶导数:

F(m)(t;N)=n=1Nnσit(ilnn)m=n=1N(nσ(lnn)m)eitlnn,F^{(m)}(t; N) = \sum_{n=1}^N n^{-\sigma-it} (-i \ln n)^m = \sum_{n=1}^N (n^{-\sigma} (\ln n)^m) e^{-i t \ln n},

后者仍然是 G(t)G(t) 的形式,所以可以按照之前的方法一起处理。之后只要格点足够密,想求任意一个 F(t;N)F(t; N),我们就可以在最近的一个格点处做泰勒展开。

[Gourdon] 和 [OS] 的在线计算

TL;DR: 确定 β,c,k0,M\beta, c, k_0, M 等参数,计算格点 {t0,t0+π/β,,t0+Mπ/β}\{t_0, t_0 + \pi / \beta, \dots, t_0 + M \pi / \beta\} 上的所有的 F(t;N)F(t; N),然后用 \eqrefeq:gourdon\eqref{eq:gourdon} 计算 \eqrefeq:Gdef\eqref{eq:G-def} 定义的 GG,最后用 \eqrefeq:decompF\eqref{eq:decomp-F} 计算 F(t;N)F(t; N)

现在我们假设我们能快速计算任何格点上的 F(t;N)F(t; N),现在我们考虑如何用格点上的 F(t;N)F(t; N) 计算非格点上 F(t;N)F(t; N)

[Odlyzko] 和 [Gourdon] 的方法差不多。相对而言,我更喜欢 [Gourdon] 的表述。由于 [Gourdon] 这块写的非常精妙,我这差不多就是他的翻译。(注:这里小节里请忘记上个小节的 GG 函数,那是个临时变量。)

首先我们有如下定理:

[Whittaker–Shannon interpolation formula] 若一个函数 G(x)G(x) 可以表达为

G(t)=ττg(x)eixtdx,G(t) = \int_{-\tau}^\tau g(x) e^{i xt} \d x,

,定义 \sinc(x)=sin(x)x\sinc(x) = \frac{\sin(x)}{x},则有

G(t)=nZG(nπτ)\sinc(τtnπ).G(t) = \sum_{n \in \mathbb{Z}} G\left( \frac{n\pi}{\tau} \right) \sinc(\tau t - n\pi).

可以看到,只要给定格点上的 GG 值,Whittaker–Shannon 公式就能给出插值出整个函数。但是这样有一个问题:收敛太慢了。现在的差值公式只用 G(nπτ)G\left(\frac{n\pi}{\tau} \right) 里的点,我们是否能通过增加格点的密度来加速收敛呢?

于是 [Gourdon] 给出了如下性质:

[Proposition 3, Gourdon] 给定两个复函数 GGhh ,如果对于任意 zz 均有 G(z)=O(eτz)|G(z)| = O(e^{\tau |\Im z|})h(z)=o(e(βτ)z)|h(z)| = o(e^{(\beta - \tau)|\Im z|})h(0)=1h(0) = 1,其中 β>τ>0\beta > \tau > 0 为两常数,则有

G(t)=nZG(nπβ)h(xnπ/β)\sinc(βxnπ).\labeleq:gourdon\begin{equation} G(t) = \sum_{n \in \mathbb{Z}} G\left( \frac{n \pi}{\beta} \right) h(x - n \pi / \beta) \sinc(\beta x - n \pi). \label{eq:gourdon} \end{equation}

证明也非常简单。我都忍不住要抄一发……

[Proof of Proposition 3, Gourdon] 固定 xx,考虑以下路径积分

CG(z)βsinβzh(xz)xzdz,\int_C G(z) \frac{\beta}{\sin \beta z} \frac{h(x - z)}{x - z} \d z,

其中 CC 是 0 为圆心,半径为 (n+1/2)π/β(n+1/2) \pi / \beta 的圆。不难看出,随着 nn 的增大,G(z)h(xz)sinβz=o(eβz)Θ(eβz)\frac{G(z) h(x - z)}{\sin \beta z} = \frac{o(e^{\beta |\Im z|})}{\Theta(e^{\beta |\Im z|})} ,故当 nn \to \infty 时,该积分值为 0。而在我们取 nn \to \infty 的极限的过程中,所有极点都被包含了进去。明显可以看出,这个积分的极点为 xx 以及所有整数 nn 对应的 nπ/βn \pi / \beta。由留数定理得

Res(x)+nZRes(nπ/β)=0,\text{Res}(x) + \sum_{n \in \mathbb{Z}} \text{Res}(n\pi/\beta) = 0,

计算可得

Res(x)=G(z)βsinβz,Res(nπ/β)=G(nπβ)1cos(nπ)h(xnπ/β)xnπ/β,\text{Res}(x) = -G(z) \frac{\beta}{\sin \beta z}, \quad \text{Res}(n \pi / \beta) = G\left( \frac{n \pi }{\beta} \right) \frac{1}{\cos (n\pi)} \frac{h(x - n \pi / \beta)}{x - n \pi / \beta},

代入整理即可。

总之,有了 \eqrefeq:gourdon\eqref{eq:gourdon},我们就可以设计一个好的 hh,通过增加格点密度来加速收敛。关于 hh 的设计,[Gourdon] 和 [Odlyzko] 不同。[Gourdon] 用的是 h(t;β,τ,m)=\sincm((βτ)t/m)h(t; \beta, \tau, m) = \sinc^m\left( (\beta - \tau)t/m \right),而 [Odlyzko] 则使用了

h(t;β,τ,c)=csinhcsinhc2ε2t2c2ε2t2,ε:=(βτ)/2.h(t; \beta, \tau, c) = \frac{c}{\sinh c} \frac{\sinh \sqrt{c^2 - \eps^2 t^2}}{\sqrt{c^2 - \eps^2t^2}}, \quad \eps:= (\beta - \tau) / 2.

最后就是这个 GG 到底是啥了。[Gourdon] 和 [Odlyzko] 都说:函数

G(t;k0,k1)=eiαtn=k0k1n1/2it,α:=lnk0k1,\labeleq:Gdef\begin{equation} G(t; k_0, k_1) = e^{-i \alpha t} \sum_{n=k_0}^{k_1} n^{-1/2 -it}, \quad \alpha := \ln \sqrt{k_0 k_1}, \label{eq:G-def} \end{equation}

对应的 τ\taulnk1lnk0\ln k_1 - \ln k_0,他们说是就是吧。这里我加了求和上下限,因为这样可以减小 τ\tau,减小格点密度,反正每次就暴力 k01k_0 - 1 次。

F(t;N):=n=1Nn1/2it=n=1k01n1/2it+G(t;k0,N).\labeleq:decompF\begin{equation} F(t; N) := \sum_{n=1}^N n^{-1/2-it} = \sum_{n=1}^{k_0 - 1} n^{-1/2 - it} + G(t; k_0, N). \label{eq:decomp-F} \end{equation}

当然对于 \eqrefeq:gourdon\eqref{eq:gourdon} 我们也不可能把所有的 nn 都用上,必须截断。这样就会有截断误差,然而我懒得分析截断误差了……而且我们求格点上的 G(t;k0,k1)G(t; k_0, k_1) 也有误差需要考虑。[Gourdon] 上的分析看得我云里雾里,我就不总结了。如果用了 [Odlyzko] 的 hh,那么我们只需要 (βτ)t/2c(\beta - \tau) t / 2 \leq ctt 就行了(因为我也不知道 εt>c\eps t > c 会发生什么……变成虚数?),而且 sinhcec/2\sinh c \approx e^c / 2h(t;β,τ,c)h(t; \beta, \tau, c) 收敛的挺快的。但是这个算法里面有一堆参数,例如 β,c,k0\beta, c, k_0,我也不知道怎么选。[Equation 4.4.21, Odlyzko] 给出了他用的参数,可以当个参考。

我看到 [Odlyzko] 的这个 hh 很眼熟呀,长得和 [FKBJ] 里的 kernel 好像。这个 kernel 起源是 [Logan],我后来一时兴起就去看了一下 [Logan] 的 paper ,发现 Abstract 里面有这么一句话

…This result confirms a conjecture of J.C. Lagarias and A.M. Odlyzko …

这不就是 [LO] 吗……难怪 [FKBJ] 会用这个 kernel 2333333

[Platt2] 的算法

没看懂……看起来他不是基于 Riemann-Siegel 公式的。就先放着吧……

下期预告

好了到这里,我们就可以均摊 \tO(1)\tO(1) 地对一个固定的 σ\sigmaζ(σ+it)\zeta(\sigma + it) 了,用最开始的 [LO] 算法或者 [Galway] 里的算法,我们就可以做到 \tO(x1/2)\tO(x^{1/2}) 的时间内求 π(x)\pi(x) 了,算是说完了一个故事了,赶紧棺材板盖上完成从入门到入土。但是 [FKBJ] 和 [Platt] 的故事并没有完全结束,因为他们依赖于找到 ζ(s)\zeta(s) 的非平凡零点。虽然我们现在已经学会如何求 ζ(s)\zeta(s) 了,但是怎么找零点显然还需要一些额外的知识,包括:如何找到包含零点的区间?如何确定零点已经被找完了,没有遗漏?预知后事如何,请听下回分解……(我真写的要吐了……)

References

  • [LO] : Lagarias and Odlyzko, “Computing π(x)\pi(x): an analytic method.”
  • [OS] : Odlyzko and Schönhage, “Fast algorithms for multiple evaluations of the Riemann zeta function”
  • [Galway] : William Floyd Galway, “Analytic Computation of the Prime-Counting Function”,
  • [FKBJ] : Franke et al., “A Practical Analytic Method for Calculating π(x)\pi (x).”
  • [Platt] : David Platt, “Computing π(x)\pi(x) Analytically.”
  • [Platt2] : David Platt, “Isolating some non-trivial zeros of zeta”
  • [de Reyna] : Juan Arias de Reyna, “High Precision Computation of Riemann’s Zeta Function by the Riemann-Siegel Formula, I”
  • [Gabcke] : Wolfgang Gabcke, “Neue Herleitung und explizite Restabschätzung der Riemann-Siegel-Formel”
  • [Zetafast] : Kurt Fischer, “The Zetafast algorithm for computing zeta functions”
  • [Brent] : Richard P. Brent, “On asymptotic approximations to the log-Gamma and Riemann-Siegel theta functions”
  • [Gourdon] : Xavier Gourdon, “The 101310^{13} first zeros of the Riemann Zeta function, and zeros computation at very large height”
  • [Logan] : Benjamin F. Logan, “Bounds for the tails of sharp-cutoff filter kernels”