Mengevaluasi Fungsi Riemann Zeta di Nomor Kompleks

11

pengantar

Saya menemukan pertanyaan ini ditutup karena tidak jelas, namun itu ide yang bagus. Saya akan melakukan yang terbaik untuk menjadikan ini tantangan yang jelas.

Fungsi Riemann Zeta adalah fungsi khusus yang didefinisikan sebagai kelanjutan analitik dari

masukkan deskripsi gambar di sini

ke pesawat kompleks. Ada banyak rumus setara untuk itu yang membuatnya menarik untuk golf kode.

Tantangan

Tulis sebuah program yang mengambil 2 float sebagai input (bagian nyata dan imajiner dari bilangan kompleks) dan mengevaluasi fungsi Riemann Zeta pada saat itu.

Aturan

  • Input dan output melalui konsol ATAU fungsi input dan nilai balik
  • Dibangun dalam bilangan kompleks tidak diizinkan, gunakan pelampung (angka, ganda, ...)
  • Tidak ada fungsi matematika kecuali + - * / pow logdan fungsi trigonometri bernilai nyata (jika Anda ingin mengintegrasikan, gunakan fungsi gamma, ... Anda harus memasukkan definisi fungsi ini dalam kode)
  • Input: 2 mengapung
  • Output: 2 mengapung
  • Kode Anda harus mengandung nilai yang memberikan presisi arbitrer secara teoritis ketika dibuat arbitrer besar / kecil
  • Perilaku pada input 1 tidak penting (ini adalah satu-satunya kutub fungsi ini)

Kode terpendek dalam byte menang!

Contoh Input dan Output

Memasukkan:

2, 0

Keluaran:

1.6449340668482266, 0

Memasukkan:

1, 1

Keluaran:

0,5821580597520037, -0.9268485643308071

Memasukkan:

-1, 0

Keluaran:

-0.08333333333333559, 0

Jens Render
sumber
1
Apa presisi keluaran yang dibutuhkan? Saya tidak yakin saya mengerti Kode Anda harus mengandung nilai yang memberikan ketepatan arbitrer secara teoritis ketika dibuat arbitrer besar / kecil . Apakah maksud Anda seperti nilai maksimum loop daripada ketika peningkatan tanpa batas memberikan peningkatan presisi? Bisakah nilai itu dikodekan?
Luis Mendo
@ DonMuesli Ini berarti ketepatan tergantung pada parameter, katakan N, yang dapat Anda berikan nilai apa pun yang Anda suka, tetapi untuk ketelitian tertentu, Anda dapat membuat N kecil atau cukup besar untuk mencapai ketepatan itu. Secara teoritis kata itu ada karena Anda tidak perlu khawatir tentang ketepatan mesin atau bahasa yang terbatas.
Jens Renders
Untuk lebih memperjelas N: apakah cukup untuk setiap ikatan epsdan masukan xada Nyang diperhitungkan di zeta(x)dalamnya eps; atau harus ada Nyang hanya bergantung pada epsdan menjamin bahwa untuk setiap x(atau mungkin untuk xlebih dari fungsi tertentu epsdari kutub) itu mencapai batas; atau mungkin Nbergantung pada x, tetapi jawaban harus menjelaskan bagaimana cara menghitung Ndiberikan xdan eps? (Teori bilangan analitis saya tidak banyak, tetapi saya menduga bahwa opsi 2 dan 3 akan melampaui semua kecuali satu atau dua poster reguler).
Peter Taylor
@PeterTaylor N cukup besar: Untuk setiap xdan untuk apa pun epsharus ada Psedemikian rupa sehingga untuk semua N>Poutput lebih dekat daripada epsnilai yang tepat. Apakah ini jelas? Apakah saya perlu mengklarifikasi untuk kasus dengan N yang cukup kecil?
Jens Renders
Tidak, itu sudah cukup jelas.
Peter Taylor

Jawaban:

8

Python - 385

Ini adalah implementasi langsung dari Equation 21 dari http://mathworld.wolfram.com/RiemannZetaFunction.html Ini menggunakan konvensi Python untuk argumen opsional; jika Anda ingin menentukan presisi, Anda bisa meneruskan argumen ketiga ke fungsi, jika tidak maka gunakan 1e-24 secara default.

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)
RT
sumber
z(2,0)memberikan nilai yang salah, harus pi ^ 2/6.
GuillaumeDufay
4

Python 3 , 303 297 byte

Jawaban ini didasarkan pada jawaban Python RT dengan beberapa modifikasi:

  • Pertama, Binomial(n, k)didefinisikan sebagai p = p * (n-k) / (k+1)yang berubah Binomial(n,k)menjadiBinomial(n,k+1) setiap lulus dari untuk loop.
  • Kedua, (-1)**k * Binomial(n,k)menjadip = p * (k-n) / (k+1) yang membalik tanda di setiap langkah loop for.
  • Ketiga, whileloop telah diubah untuk segera memeriksa apakah a*a + b*b < E.
  • Keempat, bitwise tidak Operator ~digunakan di beberapa tempat di mana mereka akan membantu dalam golf, menggunakan identitas seperti -n-1 == ~n, n+1 == -~n, dan n-1 == ~-n.

Beberapa modifikasi kecil lainnya dibuat untuk bermain golf yang lebih baik, seperti meletakkan forloop pada satu baris dan panggilan ke printpada satu baris dengan kode sebelumnya.

Saran bermain golf diterima. Cobalah online!

Edit: -6 byte dari sejumlah perubahan kecil.

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
Sherlock9
sumber
1

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

Ini juga akan menerapkan persamaan 21 dari http://mathworld.wolfram.com/RiemannZetaFunction.html Di atas harus menjadi fungsi Axiom yang ditafsirkan z (a, b) di sini 16x lebih lambat dari ini di bawah fungsi Zeta (a, b) [ yang seharusnya menjadi yang dikompilasi] semua tidak berkhianat dan berkomentar [1 detik untuk Zeta () terhadap 16 detik untuk z () untuk satu nilai 20 digit di atas titik apung]. Untuk pertanyaan digit, seseorang akan memilih presisi dengan memanggil digit (); fungsi, misalnya digit (10); z (1,1) harus mencetak 10 digit setelah titik, tetapi digit (50); z (1,1) harus mencetak 50 digit setelah titik.

-- 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)  []
RosLuP
sumber