计算复数的黎曼Zeta函数


11

介绍

我发现这个问题已经解决,因为不清楚,但这是一个好主意。我会尽力使这成为一个明确的挑战。

Riemann Zeta函数是被定义为的解析延特殊功能

在此处输入图片说明

到复杂的飞机。有许多等效的公式可以使它成为代码高尔夫的有趣之选。

挑战

编写一个程序,将2个浮点数作为输入(复数的实部和虚部),并在该点评估Riemann Zeta函数。

规则

  • 通过控制台输入或输出或功能输入和返回值
  • 不允许内置复数,请使用浮点数(数字,双精度,...)
  • 除数学函数+ - * / pow log和实数值触发函数外,没有其他数学函数(如果要积分,请使用gamma函数,...您必须在代码中包含此函数定义)
  • 输入:2个浮点数
  • 输出:2个浮点数
  • 您的代码必须包含在任意大/小情况下理论上可以给出任意精度的值
  • 输入1的行为并不重要(这是此功能的唯一作用)

以字节为单位的最短代码胜出!

输入和输出示例

输入:

2,0

输出:

1.6449340668482266,0

输入:

1、1

输出:

0.5821580597520037,-0.9268485643308071

输入:

-1,0

输出:

-0.08333333333333559,0


1
要求的输出精度是多少?我不确定我了解您的代码中包含的值必须在理论上将大/小值设为任意时给出理论上的任意精度。您是说像一个循环最大值,而不是无限增加时会提高精度吗?该值可以硬编码吗?
Luis Mendo

@DonMuesli这意味着精度取决于一个参数,例如N,您可以根据需要提供任意值,但是对于任何给定的精度,您可以将N设置得足够小或足够大,以达到该精度。理论上来说,这个词是存在的,因为您不必担心机器或语言的有限精度。
Jens Renders

为了进一步阐明N:对于任何边界eps和输入而言x,是否存在一个N计算zeta(x)为in的值是否足够eps?或必须存在一个N仅依赖于eps并保证对于任何x(或可能对某极x的给定功能而言eps)它都能达到界限的事物;或可能N取决于x,但答案应说明如何计算N给定xeps?(我的分析数论不多,但我怀疑选项2和3会超出一两个常规海报的范围)。
彼得·泰勒

@PeterTaylor N足够大:对于任何变量x,都eps必须存在一个P使得所有N>P输出都比eps实际值更接近的值。这清楚吗?对于N足够小的情况,我需要澄清吗?
Jens Renders

不,这很清楚。
彼得·泰勒

Answers:


8

蟒蛇-385

这是来自http://mathworld.wolfram.com/RiemannZetaFunction.html的Equation 21的直接实现。它使用Python的约定作为可选参数。如果要指定精度,则可以将第三个参数传递给该函数,否则默认情况下使用1e-24。

import numpy as N
def z(r,i,E=1e-24):
 R=0;I=0;n=0;
 while(True):
  a=0;b=0;m=2**(-n-1)
  for k in range(0,n+1):
   M=(-1)**k*N.product([x/(x-(n-k))for x in range(n-k+1,n+1)]);A=(k+1)**-r;t=-i*N.log(k+1);a+=M*A*N.cos(t);b+=M*A*N.sin(t)
  a*=m;b*=m;R+=a;I+=b;n+=1
  if a*a+b*b<E:break
 A=2**(1-r);t=-i*N.log(2);a=1-A*N.cos(t);b=-A*N.sin(t);d=a*a+b*b;a=a/d;b=-b/d
 print(R*a-I*b,R*b+I*a)

z(2,0)给出的值不正确,应为pi ^ 2/6。
GuillaumeDufay

4

Python 3中303个 297字节

该答案基于RT的Python答案,并作了一些修改:

  • 首先,Binomial(n, k)被定义为p = p * (n-k) / (k+1),其改变Binomial(n,k)Binomial(n,k+1)与的每通for循环。
  • 其次,(-1)**k * Binomial(n,k)成为p = p * (k-n) / (k+1)在for循环的每一步翻转符号的地方。
  • 第三,while循环已更改为立即检查是否a*a + b*b < E
  • 四,按位经营者没有~在多个地方使用他们将在高尔夫帮助,使用标识,如-n-1 == ~nn+1 == -~nn-1 == ~-n

为了更好地打高尔夫球,还进行了其他一些小的修改,例如将for循环放在一行上,并将调用print与之前的代码放在一行上。

欢迎打高尔夫球。在线尝试!

编辑: -6个字节,由一些小变化组成。

import math as N
def z(r,i,E=1e-40):
 R=I=n=0;a=b=1
 while a*a+b*b>E:
  a=b=0;p=1;m=2**~n
  for k in range(1,n+2):M=p/k**r;p*=(k-1-n)/k;t=-i*N.log(k);a+=M*N.cos(t);b+=M*N.sin(t)
  a*=m;b*=m;R+=a;I+=b;n+=1
 A=2**-~-r;t=-i*N.log(2);x=1-A*N.cos(t);y=A*N.sin(t);d=x*x+y*y;return(R*x-I*y)/d,(R*y+I*x)/d

1

公理,413个315 292字节

p(n,a,b)==(x:=log(n^b);y:=n^a;[y*cos(x),y*sin(x)]);z(a,b)==(r:=[0.,0.];e:=10^-digits();t:=p(2,1-a,-b);y:=(1-t.1)^2+t.2^2;y=0=>[];m:=(1-t.1)/y;q:=t.2/y;n:=0;repeat(w:=2^(-n-1);abs(w)<e=>break;r:=r+w*reduce(+,[(-1)^k*binomial(n,k)*p(k+1,-a,-b) for k in 0..n]);n:=n+1);[r.1*m-q*r.2,m*r.2+r.1*q])

这也将实现来自http://mathworld.wolfram.com/RiemannZetaFunction.html的等式21 上面的应该是一个迭代的公理函数z(a,b),在这里它比下面的函数Zeta(a,b)慢16倍[这应该是已编译的全部],并注释掉[Zeta()为1秒,z()为16秒,浮点后为20位的一个值)。对于数字问题,可以通过调用digits()选择精度。函数,例如digits(10); z(1,1)应该在该点之后打印10位数字,但是digits(50); z(1,1)应该在该点之后打印50位数字。

-- elevImm(n,a,b)=n^(a+i*b)=r+i*v=[r,v]
elevImm(n:INT,a:Float,b:Float):Vector Float==(x:=log(n^b);y:=n^a;[y*cos(x),y*sin(x)]::Vector Float);

--                      +oo               n
--                      ---              ---
--             1        \       1        \            n 
--zeta(s)= ---------- * /     ------  *  /    (-1)^k(   )(k+1)^(-s)
--          1-2^(1-s)   ---n  2^(n+1)    ---k         k  
--                       0                0


Zeta(a:Float,b:Float):List Float==
  r:Vector Float:=[0.,0.]; e:=10^-digits()

  -- 1/(1-2^(1-s))=1/(1-x-i*y)=(1-x+iy)/((1-x)^2+y^2)=(1-x)/((1-x)^2+y^2)+i*y/((1-x)^2+y^2)    

  t:=elevImm(2,1-a,-b);
  y:=(1-t.1)^2+t.2^2;
  y=0=>[] 
  m:=(1-t.1)/y; 
  q:=t.2/y
  n:=0
  repeat
     w:=2^(-n-1)
     abs(w)<e=>break  --- this always terminate because n increase
     r:=r+w*reduce(+,[(-1)^k*binomial(n,k)*elevImm(k+1,-a,-b) for k in 0..n])
     n:=n+1
  -- (m+iq)(r1+ir2)=(m*r1-q*r2)+i(m*r2+q*r1)
  [r.1*m-q*r.2,m*r.2+r.1*q]

this is one test for the z(a,b) function above:

(10) -> z(2,0)
   (10)  [1.6449340668 482264365,0.0]
                                              Type: List Expression Float
(11) -> z(1,1)
   (11)  [0.5821580597 520036482,- 0.9268485643 3080707654]
                                              Type: List Expression Float
(12) -> z(-1,0)
   (12)  [- 0.0833333333 3333333333 3,0.0]
                                              Type: List Expression Float
(13) -> z(1,0)
   (13)  []
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.