ประเมินฟังก์ชัน Riemann Zeta ที่จำนวนเชิงซ้อน


11

บทนำ

ฉันพบคำถามนี้ที่ถูกปิดเพราะมันไม่ชัดเจน แต่มันเป็นความคิดที่ดี ฉันจะทำให้ดีที่สุดเพื่อทำให้เรื่องนี้กลายเป็นความท้าทายที่ชัดเจน

ฟังก์ชั่นซีตา Riemannเป็นฟังก์ชั่นพิเศษที่ถูกกำหนดให้เป็นความต่อเนื่องของการวิเคราะห์

ป้อนคำอธิบายรูปภาพที่นี่

กับระนาบเชิงซ้อน มีสูตรที่เทียบเท่าหลายอย่างซึ่งทำให้มันน่าสนใจสำหรับการตีกอล์ฟ

ท้าทาย

เขียนโปรแกรมที่ใช้ 2 ลอยเป็นอินพุต (ส่วนจริงและจินตภาพของจำนวนเชิงซ้อน) และประเมินฟังก์ชัน Riemann Zeta ณ จุดนั้น

กฎระเบียบ

  • อินพุตและเอาต์พุตผ่านคอนโซลหรือฟังก์ชันอินพุตและค่าส่งคืน
  • ไม่อนุญาตให้ใช้หมายเลขที่ซับซ้อนภายในตัวใช้ลอย (หมายเลข, คู่, ... )
  • ไม่มีฟังก์ชั่นทางคณิตศาสตร์ยกเว้น+ - * / pow logและฟังก์ชั่นตรีโกณมิติมูลค่าจริง (ถ้าคุณต้องการที่จะรวมให้ใช้ฟังก์ชั่นแกมม่า ... คุณต้องรวมคำนิยามฟังก์ชั่นนี้ในรหัส)
  • อินพุต: 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)ไปภายในeps; หรือจะต้องมีอยู่Nซึ่งขึ้นอยู่กับเพียงepsและรับประกันว่าสำหรับx(หรืออาจจะxมากกว่าฟังก์ชั่นที่กำหนดepsจากเสา) ใด ๆ มันบรรลุขอบเขต; หรืออาจจะNขึ้นอยู่กับxแต่คำตอบที่ควรจะอธิบายวิธีการคำนวณNที่กำหนดxและeps? (ทฤษฎีจำนวนเชิงวิเคราะห์ของฉันยังไม่มากนัก แต่ฉันสงสัยว่าตัวเลือกที่ 2 และ 3 จะเป็นมากกว่าแค่โปสเตอร์ธรรมดาหนึ่งหรือสองรายการ)
Peter Taylor

@PeterTaylor N มีขนาดใหญ่พอ: สำหรับการใด ๆxและการใดก็ตามepsจะต้องมีอยู่Pเช่นนั้นสำหรับN>Pการส่งออกทั้งหมดอยู่ใกล้กว่าepsค่าที่แน่นอน ชัดเจนหรือไม่ ฉันจำเป็นต้องอธิบายให้ชัดเจนสำหรับกรณีที่มี N ขนาดเล็กเพียงพอหรือไม่
Jens Renders

ไม่ชัดเจนพอ
Peter Taylor

คำตอบ:


8

Python - 385

นี่เป็นการดำเนินการที่ซับซ้อนของ Equation 21 จากhttp://mathworld.wolfram.com/RiemannZetaFunction.htmlสิ่งนี้ใช้การประชุมแบบ 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 bytes

คำตอบนี้ขึ้นอยู่กับคำตอบ Python ของ RT ที่มีการแก้ไขหลายประการ:

  • ครั้งแรกที่Binomial(n, k)ถูกกำหนดให้เป็นp = p * (n-k) / (k+1)ซึ่งการเปลี่ยนแปลงBinomial(n,k)ที่จะBinomial(n,k+1)มีการส่งผ่านของห่วงทุก
  • ประการที่สอง(-1)**k * Binomial(n,k)กลายเป็นp = p * (k-n) / (k+1)ที่พลิกสัญญาณในทุกขั้นตอนของการวนรอบ
  • ประการที่สามห่วงมีการเปลี่ยนแปลงในการตรวจสอบทันทีหากwhilea*a + b*b < E
  • ประการที่สี่บิตผู้ประกอบการไม่ได้~ถูกนำมาใช้ในหลายสถานที่ที่พวกเขาจะช่วยในการเล่นกอล์ฟโดยใช้อัตลักษณ์เช่น-n-1 == ~n, และn+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])

นี่จะใช้สมการที่ 21 จากhttp://mathworld.wolfram.com/RiemannZetaFunction.html ข้างต้นควรเป็นฟังก์ชัน Axiom ที่แปลความหมาย z (a, b) ที่นี่ 16x ช้ากว่าฟังก์ชันด้านล่าง Zeta (a, b) [ นั่นควรจะเป็นหนึ่งในการคอมไพล์] ทั้งหมด ungolfed และแสดงความคิดเห็น [1 วินาทีสำหรับ Zeta () กับ 16 วินาทีสำหรับ z () สำหรับหนึ่งค่า 20 หลักหลังจุดลอย] สำหรับคำถามหลักหนึ่งจะเลือกความแม่นยำโดยการเรียกตัวเลข (); ฟังก์ชั่นเช่นตัวเลข (10); z (1,1) ควรพิมพ์ 10 หลักหลังจากจุด แต่ตัวเลข (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)  []
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.