Đánh giá hàm Riemann Zeta ở số phức


11

Giới thiệu

Tôi thấy câu hỏi này đã bị đóng vì không rõ ràng, nhưng đó là một ý tưởng hay. Tôi sẽ làm hết sức mình để biến điều này thành một thử thách rõ ràng.

Hàm Riemann Zeta là một hàm đặc biệt được định nghĩa là sự tiếp tục phân tích của

nhập mô tả hình ảnh ở đây

đến mặt phẳng phức. Có nhiều công thức tương đương cho nó làm cho nó thú vị cho mã golf.

Thử thách

Viết chương trình lấy 2 số float làm đầu vào (phần thực và phần ảo của một số phức) và đánh giá hàm Riemann Zeta tại điểm đó.

Quy tắc

  • Đầu vào và đầu ra thông qua bàn điều khiển HOẶC chức năng nhập và trả về giá trị
  • Không được phép xây dựng số phức, sử dụng số float (số, gấp đôi, ...)
  • Không có hàm toán học nào ngoại trừ + - * / pow logvà các hàm trig có giá trị thực (nếu bạn muốn tích hợp, hãy sử dụng hàm gamma, ... bạn phải bao gồm định nghĩa hàm này trong mã)
  • Đầu vào: 2 phao
  • Đầu ra: 2 phao
  • Mã của bạn phải chứa giá trị mang lại độ chính xác về mặt lý thuyết khi được thực hiện lớn / nhỏ tùy ý
  • Hành vi ở đầu vào 1 không quan trọng (đây là cực duy nhất của chức năng này)

Mã ngắn nhất trong byte thắng!

Ví dụ đầu vào và đầu ra

Đầu vào:

2, 0

Đầu ra:

1.6449340668482266, 0

Đầu vào:

1, 1

Đầu ra:

0,5821580597520037, -0.9268485643308071

Đầu vào:

-1, 0

Đầu ra:

-0,08333333333333559, 0


1
Độ chính xác đầu ra cần thiết là gì? Tôi không chắc chắn tôi hiểu Mã của bạn phải chứa giá trị mang lại độ chính xác về mặt lý thuyết khi được tạo lớn / nhỏ tùy ý . Bạn có nghĩa là giống như một giá trị tối đa của vòng lặp so với khi tăng mà không bị ràng buộc sẽ tăng độ chính xác? Giá trị đó có thể được mã hóa cứng?
Luis Mendo

@DonMuesli Điều này có nghĩa là độ chính xác phụ thuộc vào một tham số, giả sử N, bạn có thể đưa ra bất kỳ giá trị nào bạn thích, nhưng với bất kỳ độ chính xác nào, bạn có thể làm cho N nhỏ hoặc đủ lớn để đạt được độ chính xác đó. Về mặt lý thuyết là có bởi vì bạn không phải lo lắng về độ chính xác hạn chế của máy hoặc ngôn ngữ.
Jens Render

Để làm rõ hơn N: có đủ cho bất kỳ ràng buộc epsvà đầu vào xnào tồn tại một Ntính toán zeta(x)bên trong eps; hoặc phải tồn tại một Ncái chỉ phụ thuộc epsvà đảm bảo rằng đối với bất kỳ x(hoặc có lẽ cho bất kỳ xchức năng nào epstừ cực) đã đạt được ràng buộc; hoặc có thể Nphụ thuộc vào x, nhưng câu trả lời sẽ giải thích cách tính toán đã Ncho xeps? (Lý thuyết số phân tích của tôi không nhiều, nhưng tôi nghi ngờ rằng các tùy chọn 2 và 3 sẽ vượt xa tất cả trừ một hoặc hai áp phích thông thường).
Peter Taylor

@PeterTaylor N đủ lớn: Đối với bất kỳ xvà cho bất kỳ epsphải có tồn tại Psao cho tất cả N>Pđầu ra gần với epsgiá trị chính xác. Điều này có rõ ràng không? Tôi có cần phải làm rõ nó cho trường hợp với N đủ nhỏ không?
Jens Render

Không, điều đó đủ rõ ràng.
Peter Taylor

Câu trả lời:


8

Con trăn - 385

Đây là cách triển khai đơn giản của phương trình 21 từ http://mathworld.wolfram.com/RiemannZetaFunction.html Điều này sử dụng quy ước của Python cho các đối số tùy chọn; nếu bạn muốn chỉ định độ chính xác, bạn có thể truyền đối số thứ ba cho hàm, nếu không, nó sử dụng 1e-24 theo mặc định.

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)đưa ra một giá trị không chính xác, nên là pi ^ 2/6.
GuillaumeDufay

4

Python 3 , 303 297 byte

Câu trả lời này dựa trên câu trả lời Python của RT với một số sửa đổi:

  • Thứ nhất, Binomial(n, k)được định nghĩa là p = p * (n-k) / (k+1)làm thay đổi Binomial(n,k)đến Binomial(n,k+1)với tất cả các lộ trình qua các vòng lặp for.
  • Thứ hai, (-1)**k * Binomial(n,k)trở thành p = p * (k-n) / (k+1)cái lật các dấu hiệu ở mỗi bước của vòng lặp for.
  • Thứ ba, whilevòng lặp đã được thay đổi để kiểm tra ngay nếu a*a + b*b < E.
  • Thứ tư, Bitwise không điều hành ~được sử dụng ở một số nơi họ sẽ hỗ trợ trong việc chơi golf, sử dụng sắc như -n-1 == ~n, n+1 == -~n, và n-1 == ~-n.

Một số sửa đổi nhỏ khác đã được thực hiện để chơi golf tốt hơn, chẳng hạn như đặt forvòng lặp trên một dòng và gọi đến printmột dòng với mã trước nó.

Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

Chỉnh sửa: -6 byte từ một số thay đổi nhỏ.

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

Tiên đề, 413 315 292 byte

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])

Điều này cũng sẽ thực hiện phương trình 21 từ http://mathworld.wolfram.com/RiemannZetaFunction.html Ở trên nên là hàm Axiom lặp lại z (a, b) ở đây chậm hơn 16 lần so với hàm Zeta (a, b) bên dưới đó phải là phần được biên dịch] tất cả không được chỉnh sửa và nhận xét [1 giây cho Zeta () so với 16 giây cho z () cho một giá trị 20 chữ số sau điểm nổi]. Đối với câu hỏi chữ số, người ta sẽ chọn độ chính xác bằng cách gọi các chữ số (); hàm, ví dụ chữ số (10); z (1,1) nên in 10 chữ số sau điểm, nhưng chữ số (50); z (1,1) nên in 50 chữ số sau điểm.

-- 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)  []
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.