複素数でのリーマンゼータ関数の評価


11

前書き

私が見つかりました。この質問、それは不明であったために閉鎖された、まだそれはいいアイデアでした。これを明確な課題にするために最善を尽くします。

リーマンゼータ関数はの解析接続として定義されている特殊機能であります

ここに画像の説明を入力してください

複雑な平面に。それには多くの同等の公式があり、コードゴルフにとって興味深いものとなっています。

チャレンジ

入力として2つの浮動小数点数(複素数の実数部と虚数部)を取り、その点でリーマンゼータ関数を評価するプログラムを作成します。

ルール

  • コンソール経由の入出力または関数の入力と戻り値
  • 組み込みの複素数は許可されていません。float(number、double、...)を使用してください
  • 以外の数学関数+ - * / pow logおよび実数値のトリガー関数はありません(統合する場合は、ガンマ関数を使用します。...この関数定義をコードに含める必要があります)
  • 入力:2フロート
  • 出力:2フロート
  • コードには、任意の大/小にしたときに理論的に任意の精度を与える値が含まれている必要があります
  • 入力1での動作は重要ではありません(これがこの関数の唯一の極です)

バイト単位の最短コードが勝ちです!

入力と出力の例

入力:

2、0

出力:

1.6449340668482266、0

入力:

1、1

出力:

0.5821580597520037、-0.9268485643308071

入力:

-1、0

出力:

-0.08333333333333559、0


1
必要な出力精度は何ですか?あなたのコードには、任意の大/小にしたときに理論的に任意の精度を与える値が含まれている必要があることを理解していません。制限なしで増加すると精度が向上するよりも、ループの最大値のような意味ですか?その値をハードコーディングできますか?
ルイスメンドー

@DonMuesliこれは、精度がパラメーター(Nなど)に依存することを意味します。これは任意の値を指定できますが、任意の精度で、Nをその精度を達成するのに十分な大きさにすることができます。機械または言語の限られた精度を心配してはならないため、理論的にはこの言葉があります。
ジェンズレンダリング

さらにNを明確にする:それは十分である任意の結合のためにeps、入力がx存在しNている計算をzeta(x)以内にeps、または、任意の(または極からの特定の関数を超える)Nのみに依存し、それepsを保証するものが存在する必要があります。またはに依存する可能性がありますが、答えは与えられた計算方法を説明する必要がありますか?(私の分析的数論はそれほど大きくはありませんが、オプション2と3は通常のポスターが1つか2つを除くすべてを超えると思われます)。xxepsNxNxeps
ピーターテイラー

@PeterTaylor N十分な大きさ:いずれかのためにx、任意のためにeps存在する必要がありP、このようなすべてのためにそのN>P出力が近いよりeps正確な値です。これは明らかですか?Nが十分に小さい場合にそれを明確にする必要がありますか?
イェンスレンダリング

いいえ、それは十分明らかです。
ピーターテイラー

回答:


8

パイソン-385

これは、http://mathworld.wolfram.com/RiemannZetaFunction.htmlからの式21の単純な実装ですこれは、オプションの引数にPythonの規則を使用しています。精度を指定する場合、3番目の引数を関数に渡すことができます。それ以外の場合は、デフォルトで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の3303 297バイト

この回答は、いくつかの変更を加えたRTのPython回答に基づいています。

  • まず、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) forループの各ステップで記号を反転するた。
  • 第三に、whileループが変更されて、すぐにa*a + b*b < E
  • 第四に、ビット単位のないオペレータは~、このようなとしてのアイデンティティを使用して、彼らはゴルフのに役立つだろういくつかの場所で使用されている-n-1 == ~nn+1 == -~nn-1 == ~-n

より良いゴルフのために、forループを1行に配置し、printを1行に配置し、コードをその前に1行で。

ゴルフの提案を歓迎します。オンラインでお試しください!

編集:いくつかの小さな変更から-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

公理、413315292バイト

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も実装します。上記のAxiom関数z(a、b)は、以下の関数Zeta(a、b)[それはコンパイルされたものであるべきである]すべての制限なしとコメント[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)  []
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.