メルセンヌ素数とは、 2^P-1 の形の素数です。(Pは自然数) 2進数で示すと全て 1 の立った形になります。
新メルセンヌ素数を発見できる速度のプログラムを作りたい場合は、 Richard Crandallさん作成のlucdwt.c が参考になります。 http://www.perfsci.com/free-software.asp#giantint にはそれ以外にも楕円曲線法やストラッセン乗算法など巨大数を扱う Cソースがいろいろあります。
linux に DOSBOX をインストールし DOSBOX を起動 $dosbox ubasicのある場所が/tmpなら/tmpをC:ドライブに指定 >mount c /tmp ubasic を起動 >C:ubv32.exe プログラムを /tmp/TEST.UB という名前で用意しておいて load >load "test" 実行 >run
4 要素のフーリエ変換を使って多倍長の乗算をしてみます。
4 要素なので 4 乗した時に 1 になる 4 乗根 (0,1) を使います。
(8 要素の場合は当然 8 乗根を使います)
12 の 2 乗を計算してみます。
まず 12 を多倍長の表現に変換します。
( 0, 0) ( 0, 0) ( 1, 0) ( 2, 0)
次に 4 要素の順フーリエ変換を行います。
( 0, 1)*( 0, 0)+(-1, 0)*( 0, 0)+( 0,-1)*( 1, 0)+( 1, 0)*( 2, 0) =( 2,-1)
(-1, 0)*( 0, 0)+( 1, 0)*( 0, 0)+(-1, 0)*( 1, 0)+( 1, 0)*( 2, 0) =( 1, 0)
( 0,-1)*( 0, 0)+(-1, 0)*( 0, 0)+( 0, 1)*( 1, 0)+( 1, 0)*( 2, 0) =( 2, 1)
( 1, 0)*( 0, 0)+( 1, 0)*( 0, 0)+( 1, 0)*( 1, 0)+( 1, 0)*( 2, 0) =( 3, 0)
次に各要素を 2 乗して、 4 要素なので正規化する為に 4 で割ります。
( 2,-1)*( 2,-1)/4=( 0.75,-1)
( 1, 0)*( 1, 0)/4=( 0.25, 0)
( 2, 1)*( 2, 1)/4=( 0.75, 1)
( 3, 0)*( 3, 0)/4=( 2.25, 0)
次に 4 要素の逆フーリエ変換を行います。
( 0,-1)*( 0.75,-1)+(-1, 0)*( 0.25, 0)+( 0, 1)*( 0.75, 1)+( 1, 0)*( 2.25, 0)=( 0, 0)
(-1, 0)*( 0.75,-1)+( 1, 0)*( 0.25, 0)+(-1, 0)*( 0.75, 1)+( 1, 0)*( 2.25, 0)=( 1, 0)
( 0, 1)*( 0.75,-1)+(-1, 0)*( 0.25, 0)+( 0,-1)*( 0.75, 1)+( 1, 0)*( 2.25, 0)=( 4, 0)
( 1, 0)*( 0.75,-1)+( 1, 0)*( 0.25, 0)+( 1, 0)*( 0.75, 1)+( 1, 0)*( 2.25, 0)=( 4, 0)
これで回答、
( 0, 0) ( 1, 0) ( 4, 0) ( 4, 0)
が求まりました。実際の計算で要素数が増えてくると誤差が出て来てちょうど整数には
ならないので四捨五入してやります。(あまりにも誤差が大きい場合は要素数を増やす)
フーリエ変換には FFT が使えるので桁が増えた場合には素直に計算する場合に比較し
て大変高速になります。この方法は東大計算機センターの金田さんによりπの世界記録
をだすのにも使用されています。
ちょっと補足
( 1, 0) は、複素数の実部が 1 虚部が 0 の数を表しています。
( 0, 1)*( , )+(-1, 0)*( , )+( 0,-1)*( , )+( 1, 0)*( , )
(-1, 0)*( , )+( 1, 0)*( , )+(-1, 0)*( , )+( 1, 0)*( , )
( 0,-1)*( , )+(-1, 0)*( , )+( 0, 1)*( , )+( 1, 0)*( , )
( 1, 0)*( , )+( 1, 0)*( , )+( 1, 0)*( , )+( 1, 0)*( , )
ここに出て来る定数は回転子と
いいます。右 中央の 4 乗根の (0,1) から始めて 上側にその 2 乗 3 乗 と続き
それぞれを 左側に 2 乗 3 乗 4 乗した数になっています。逆フーリエ変換の時は
(0,1) の逆数の (0,-1) から始めます。
実際は FFT のプログラムを流用してコーディングされると思うのですが世の中に
流通している FFT は正規化をしないものした後の値を返却するものなどいろいろで
す、入手したプログラムとここに書いた値の差を見て多倍長乗算のプログラムを作
成してください。
8要素の FT の回転子は
0 1 2 3 4 5 6 7
0(-0.57, 0.57) ( 0 , 1 ) (-0.57, 0.57) (-1 , 0 ) (-0.57,-0.57) ( 0 ,-1 ) ( 0.57,-0.57) ( 1 , 0 )
1( 0 , 1 ) (-1 , 0 ) ( 0 ,-1 ) ( 1 , 0 ) ( 0 , 1 ) (-1 , 0 ) ( 0 ,-1 ) ( 1 , 0 )
2(-0.57, 0.57) ( 0 ,-1 ) ( 0.57, 0.57) (-1 , 0 ) ( 0.57,-0.57) ( 0 , 1 ) (-0.57,-0.57) ( 1 , 0 )
3(-1 , 0 ) ( 1 , 0 ) (-1 , 0 ) ( 1 , 0 ) (-1 , 0 ) ( 1 , 0 ) (-1 , 0 ) ( 1 , 0 )
4(-0.57,-0.57) ( 0 , 1 ) ( 0.57,-0.57) (-1 , 0 ) ( 0.57, 0.57) ( 0 ,-1 ) (-0.57, 0.57) ( 1 , 0 )
5( 0 ,-1 ) (-1 , 0 ) ( 0 , 1 ) ( 1 , 0 ) ( 0 ,-1 ) (-1 , 0 ) ( 0 , 1 ) ( 1 , 0 )
6( 0.57,-0.57) ( 0 ,-1 ) (-0.57,-0.57) (-1 , 0 ) (-0.57, 0.57) ( 0 , 1 ) ( 0.57, 0.57) ( 1 , 0 )
7( 1 , 0 ) ( 1 , 0 ) ( 1 , 0 ) ( 1 , 0 ) ( 1 , 0 ) ( 1 , 0 ) ( 1 , 0 ) ( 1 , 0 )
FFT 風に書くと
a(0) t(0)=a(0)+a(4) a(0)=t(0)+ t(4) t(0)=a(0)+ a(4) a(0)=t(0)
a(1) t(1)=a(0)-a(4) a(1)=t(0)- t(4) t(1)=a(0)- a(4) a(1)=t(4)
a(2) t(2)=a(1)+a(5) a(2)=t(1)+(0,1)*t(5) t(2)=a(1)+( 0 ,1 )*a(5) a(2)=t(2)
a(3) → t(3)=a(1)-a(5) → a(3)=t(1)-(0,1)*t(5) → t(3)=a(1)-( 0 ,1 )*a(5) → a(3)=t(6)
a(4) t(4)=a(2)+a(6) a(4)=t(2)+ t(6) t(4)=a(2)+( 0.57,0.57)*a(6) a(4)=t(1)
a(5) t(5)=a(2)-a(6) a(5)=t(2)- t(6) t(5)=a(2)-( 0.57,0.57)*a(6) a(5)=t(5)
a(6) t(6)=a(3)+a(7) a(6)=t(3)+(0,1)*t(7) t(6)=a(3)+(-0.57,0.57)*a(7) a(6)=t(3)
a(7) t(7)=a(3)-a(7) a(7)=t(3)-(0,1)*t(7) t(7)=a(3)-(-0.57,0.57)*a(7) a(7)=t(7)
フーリエ変換と同じように代数体を使っても多倍長の乗算が
できます。
17 による剰余演算を使って 4 要素の多倍長乗算をしてみます。
4 要素なので 17 を法とした演算で 4 乗した時に 1 になる
4 乗根 4 を使います。
これも 12 の 2 乗を計算してみます。
まず 12 を多倍長の表現に変換します。
0 0 1 2
次に 代数体上で 4 要素の順変換を行います。
(全て 17 を法とする剰余演算であることに注意)
4 * 0 + 16 * 0 +13 * 1 + 1 * 2 = 15
16 * 0 + 1 * 0 +16 * 1 + 1 * 2 = 1
13 * 0 + 16 * 0 + 4 * 1 + 1 * 2 = 6
1 * 0 + 1 * 0 + 1 * 1 + 1 * 2 = 3
次に各要素を 2 乗して、 4 要素なので正規化する
為に 代数体上の 4 の逆数である 13 をかけます。
(除算とはかけて 1 になる数をかける事と同値)
15 *15 * 13 = 1
1 * 1 * 13 = 13
6 * 6 * 13 = 9
3 * 3 * 13 = 15
次に 代数体上で 4 要素の逆の変換を行います。
13 * 1 + 16 *13 + 4 * 9 + 1 * 15 = 0
16 * 1 + 1 *13 +16 * 9 + 1 * 15 = 1
4 * 1 + 16 *13 +13 * 9 + 1 * 15 = 4
1 * 1 + 1 *13 + 1 * 9 + 1 * 15 = 4
これで回答
0 1 4 4
が求まりました。基数が10進だろうと5進だろうと 12*12 は
144 だということがわかります。代数体の演算にも FFT と
同じような演算量節約法が使えますし、法を 2^n+1 の素数
にとることによりシフトと加減算で簡単に剰余演算を行うこ
とができます。(法は素数な必要があります)
代数体を使った多倍長演算にどのように FFT のような演算の節約が適用
できるか考えます。
今度は 17 による剰余演算を使って 8 要素の多倍長乗算によって考えてみます。
8 要素なので 17 を法とした演算で 8 乗した時に 1 になる
8 乗根 2 を使います。
これも 12 の 2 乗を計算してみます。
まず 12 を多倍長の表現に変換します。
0 0 0 0 0 0 1 2
次に 代数体上で 8 要素の正の変換を行います。
(全て 17 を法とする剰余演算であることに注意)
0 2 * 0 + 4 * 0 + 8 * 0 + 16 * 0 + 15 * 0 + 13 * 0 + 9 * 1 + 1 * 2 = 11
1 4 * 0 + 16 * 0 + 13 * 0 + 1 * 0 + 4 * 0 + 16 * 0 + 13 * 1 + 1 * 2 = 15
2 8 * 0 + 13 * 0 + 2 * 0 + 16 * 0 + 9 * 0 + 4 * 0 + 15 * 1 + 1 * 2 = 0
3 16 * 0 + 1 * 0 + 16 * 0 + 1 * 0 + 16 * 0 + 1 * 0 + 16 * 1 + 1 * 2 = 1
4 15 * 0 + 4 * 0 + 9 * 0 + 16 * 0 + 2 * 0 + 13 * 0 + 8 * 1 + 1 * 2 = 10
5 13 * 0 + 16 * 0 + 4 * 0 + 1 * 0 + 13 * 0 + 16 * 0 + 4 * 1 + 1 * 2 = 6
6 9 * 0 + 13 * 0 + 15 * 0 + 16 * 0 + 8 * 0 + 4 * 0 + 2 * 1 + 1 * 2 = 4
7 1 * 0 + 1 * 0 + 1 * 0 + 1 * 0 + 1 * 0 + 1 * 0 + 1 * 1 + 1 * 2 = 3
これを FFT 風にしてみると
a(0) t(0)=8*a(0)+ 9*a(4) a(0)=4*t(0)+13*t(4) t(0)=1*a(0)+16*a(4) a(0)=t(0)
a(1) t(1)= a(4)+ a(0) a(1)= t(4)+ t(0) t(1)= a(4)+ a(0) a(1)=t(4)
a(2) t(2)=4*a(1)+13*a(5) a(2)=4*t(1)+13*t(5) t(2)=1*a(1)+16*a(5) a(2)=t(2)
a(3) → t(3)= a(5)+ a(1) → a(3)= t(5)+ t(1) → t(3)= a(5)+ a(1) → a(3)=t(6)
a(4) t(4)=2*a(2)+15*a(6) a(4)=1*t(2)+16*t(6) t(4)=1*a(2)+16*a(6) a(4)=t(1)
a(5) t(5)= a(6)+ a(2) a(5)= t(6)+ t(2) t(5)= a(6)+ a(2) a(5)=t(5)
a(6) t(6)=1*a(3)+16*a(7) a(6)=1*t(3)+16*t(7) t(6)=1*a(3)+16*a(7) a(6)=t(3)
a(7) t(7)= a(7)+ a(3) a(7)= t(7)+ t(3) t(7)= a(7)+ a(3) a(7)=t(7)
これで上の計算と同じ結果が得られます。かなりの演算量の節約になっています。
これでプログラム(FORTRAN77!)を書くと
integer ia(8)
integer iw1(12),iw2(12)
data ia / 1, 2, 0, 0, 0, 0, 0, 0/
n=17
c n=257
write(*,3) ia
call initfft(iw1,iw2,n,1)
write(*,1) iw1
write(*,2) iw2
call fft(ia,iw1,iw2,n)
do i=1,8
ia(i)=mod(ia(i)*ia(i),n)
c 8 で割る(8 を掛けて 1 になる数を掛ける)
ia(i)=mod(ia(i)*15,n)
c ia(i)=mod(ia(i)*225,n)
enddo
call initfft(iw1,iw2,n,-1)
write(*,1) iw1
write(*,2) iw2
call fft(ia,iw1,iw2,n)
write(*,4) ia
1 format('iw1 =',12i4)
2 format('iw2 =',12i4)
3 format('input =', 8i4)
4 format('output=', 8i4)
end
subroutine fft(ia,iw1,iw2,n)
integer ia(8),it(8)
integer iw1(12),iw2(12)
i1=1
do j=1,3
do i=1,4
it(i*2-1)=mod(ia(i)+ia(i+4),n)
itt=mod(iw1(i1)*ia(i),n)+mod(iw2(i1)*ia(i+4),n)
it(i*2)=mod(itt,n)
i1=i1+1
enddo
do i=1,8
ia(i)=it(i)
enddo
enddo
ia(1)=it(1)
ia(2)=it(5)
ia(3)=it(3)
ia(4)=it(7)
ia(5)=it(2)
ia(6)=it(6)
ia(7)=it(4)
ia(8)=it(8)
end
subroutine initfft(iw1,iw2,n,if)
integer iw1(12),iw2(12)
i1=1
i2=n-1
c 原始 8 乗根 (逆変換の時は逆数)
i3=2
if(if.eq.-1) i3=9
c i3=4
c if(if.eq.-1) i3=193
i5=1
i6=4
i9=1
do j=1,3
i10=i1
i11=i2
do i7=1,i6
do i8=1,i5
iw1(i9)=i10
iw2(i9)=i11
i9=i9+1
enddo
i10=mod(i10*i3,n)
i11=mod(i11*i3,n)
enddo
i5=i5*2
i6=i6/2
i3=mod(i3*i3,n)
enddo
end
となります。(実際は mod の計算など全てが高速になるようにプログラム
しなければいけません)
このプログラムで答えがあうのは、桁が 8 桁を越えないのはもちろん
ですが、筆算で書いたときの中間和が 17 以上にならない必要もあります。
例えば
3 3
* 3 3
---------------
9 9
9 9
---------------
9 18 9
18 で 17 以上なのでこの場合は答えがあいません。( 9 1 9 となる)
おまけ 17 を 法とする 九九表
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
---+---------------------------------------------------------------
1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2 | 2 4 6 8 10 12 14 16 1 3 5 7 9 11 13 15
3 | 3 6 9 12 15 1 4 7 10 13 16 2 5 8 11 14
4 | 4 8 12 16 3 7 11 15 2 6 10 14 1 5 9 13
5 | 5 10 15 3 8 13 1 6 11 16 4 9 14 2 7 12
6 | 6 12 1 7 13 2 8 14 3 9 15 4 10 16 5 11
7 | 7 14 4 11 1 8 15 5 12 2 9 16 6 13 3 10
8 | 8 16 7 15 6 14 5 13 4 12 3 11 2 10 1 9
9 | 9 1 10 2 11 3 12 4 13 5 14 6 15 7 16 8
10 | 10 3 13 6 16 9 2 12 5 15 8 1 11 4 14 7
11 | 11 5 16 10 4 15 9 3 14 8 2 13 7 1 12 6
12 | 12 7 2 14 9 4 16 11 6 1 13 8 3 15 10 5
13 | 13 9 5 1 14 10 6 2 15 11 7 3 16 12 8 4
14 | 14 11 8 5 2 16 13 10 7 4 1 15 12 9 6 3
15 | 15 13 11 9 7 5 3 1 16 14 12 10 8 6 4 2
16 | 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
上の変換はさらに
a(0) t(0)=8*(a(0)-a(4)) a(0)=4*(t(0)-t(4)) t(0)=1*(a(0)-a(4)) a(0)=t(0)
a(1) t(1)= a(4)+a(0) a(1)= t(4)+t(0) t(1)= a(4)+a(0) a(1)=t(4)
a(2) t(2)=4*(a(1)-a(5)) a(2)=4*(t(1)-t(5)) t(2)=1*(a(1)-a(5)) a(2)=t(2)
a(3) → t(3)= a(5)+a(1) → a(3)= t(5)+t(1) → t(3)= a(5)+a(1) → a(3)=t(6)
a(4) t(4)=2*(a(2)-a(6)) a(4)=1*(t(2)-t(6)) t(4)=1*(a(2)-a(6)) a(4)=t(1)
a(5) t(5)= a(6)+a(2) a(5)= t(6)+t(2) t(5)= a(6)+a(2) a(5)=t(5)
a(6) t(6)=1*(a(3)-a(7)) a(6)=1*(t(3)-t(7)) t(6)=1*(a(3)-a(7)) a(6)=t(3)
a(7) t(7)= a(7)+a(3) a(7)= t(7)+t(3) t(7)= a(7)+a(3) a(7)=t(7)
と書けそうです。
2 進法の計算機では、2^P による乗余の計算は 2^P-1 との and だけで 実現できます。 2^P+1 による乗余は、2^P-1 との and から 2^P で 割った結果(シフト で実現できます)を引くことで実現できます。結果が負になった場合は、2^P+1 を加算します。
2^(2^n)+1 の形の数はフェルマー数と呼ばれて Fn で表されます。 F1 〜 F4 は素数ですがそれ以上の数に素数は見つかっていません。
2^32+1 ぐらいが法に適当なのですが上に書いたように 2^32+1 は素数 ではないので大きな n に対する n 乗根を見つけることができません。 F5 = 232+1 = 4294967297 = 641 x 6700417 なので、641 と 6700417 を法とする演算で調べてみましたが、128 乗 根が最大で 256 乗根は存在しないようです。
上に書いたように 2^32+1 以上では適当な n 乗根を見つけることはで きません。そこで再帰的に演算を適用することを考えてみましょう。 例えば 2^1048576 位の演算をしようと思えば 2^1024+1 を法にして 1024 要素の順変換(2^1024+1 の 1024 乗根はすぐに見つかります)をす ると 2^1024 の大きさの要素が 1024 個できます。それぞれに今度は 2^32+1 を法として 32 要素の順変換をします。すると 2^32 の大きさ の要素が 1024*32 個できます。この要素それぞれを乗算して 逆変換をす ると乗算結果が求まります。この時に各演算の回転子は 2^(2^n)+1 を 法にする限り 2 の巾になるので乗算はシフトだけで済み命令で直接扱え る長さを越えるような乗算も高速に可能です。 http://www.craig-wood.com/nick/armprime/math.html には、2^64-2^32+1 を法に使った整数型 DWT を作成された方の方法があります。
今度は再帰的に演算を適用するのではなくて、他の 2^(2^n)+1 とお 互いに素(最大公約数が 1) な法で 同じ要素数で順変換します。2 つの法 はお互いに素なので 2 つの結果から 2 の法の積までの結果が求められる はずです。
http://www.cs.t-kougei.ac.jp/nsim/index.html 円周率の世界記録で有名な後先生の研究室です。 FFT を多重に適用することによって浮動小数点の精度を節約する方法など 役にたちそうです。
ある素数 p を法にした場合の原始 n 乗根が存在する必要十分条件は、
p = 1 mod n
です。
2^p-1(p は素数) の形をもつ整数でメルセンヌ素数にならない合成数は q = +/-1 (mod 8) and q = 2kp + 1 の形の約数しかもちません。 2kp+1 で、2^p-1 が割り切れるかを確かめる場合は直接除算をせずに 2kp+1 を法とする剰余演算で 2^p-1 を計算して 0 になるかを確かめる。 2kp+1 を 3,5 などの小さな素数で割って合成数を排除するのも有効です。 この方法をルーカスチェックの前にかけることで高速化できます。 また、p が 4 で割ってあまりが 3 になり、 2*p+1 が素数の場合は、 2*p+1 で 2^p+1 が割り切れる。
FFT の回転子の実部、虚部は、-1〜1 の範囲の数なので固定小数点を 使った演算が可能です。MMX命令が使えるかもしれません。(mersenne.org でも K6用のプログラムは固定小数点を使っているそうです。)
素数を法に使った計算では剰余の演算速度が全体の性能に大きく効いて
きます。こんなことが「計算の効率化とその限界」に書いてありました。
p = 2^l - d d が 2^l より十分に小さい
場合に x が 2^l 以上の場合に 2^l を越える分を xu 未満を xl と
すると 2^l = d mod p から
x = d*xu + xl mod p
が成立ちます。x がまだ p より大きい場合はこの計算を繰り返します。
d^2 が p 未満 の場合には 3 回で収束することが知られています。
テストプログラムです。
integer p,l,d,x,xu,xl,xa
p=11213
l=14
d=2**l-p
x=2**17-1
write(*,*) ' p=',p,' l=',l,' d=',d,' d**2=',d*d
write(*,*) ' mod(x,p)= ',mod(x,p)
xa=x
do i=1,7
xu=rshift(xa,l)
xl=and(xa,2**l-1)
xa=d*xu + xl
write(*,*) ' xu= ',xu,' xl= ',xl,' xa= ',xa
enddo
end
d を小さくするために p と l の差が小さい必要があるので p には
2 の冪乗になるべく近い素数を選ぶ必要があります。
2^16 以下で 128 乗根を持つなるべく大きい素数を探すと
i=2**16+1
1 continue
i=i-128
do j=3,2**8,2
if(mod(i,j).eq.0) then
write(*,*) i,' devide by ',j
goto 1
endif
enddo
write(*,*) ' prime= ',i
end
21164:~#a.out
65409 can devide 3
65281 can devide 97
65153 can devide 11
65025 can devide 3
64897 can devide 7
64769 can devide 239
64641 can devide 3
prime= 64513
がみつかりました。
ここまでは、整数のみを扱ってきましたが小数点以下の数を扱うにはどうし たらよいでしょうか。今の方法で例えば 4 桁の数 a b c d を a*x^3 + b*x^2 + c*x^1 + d と表して x に 10 が入った場合が 10 進法でした。では、 x に 0.1 を入れる とどうなるでしょうか。 d.cba という小数点以下を表す数になるはずです。 大きい整数の計算も小数点以下の計算も繰り上がり処理の方向が違うだけでそ れまでは全く同じ計算でできそうです。これで、円周率の多倍長計算もできそ うですね。
real*8 a(4)
real*8 t,err,tt
integer*8 n
integer*8 plan1
integer*8 plan2
include "/usr/local/include/fftw3.f"
c 4 要素の FFT を使う
n=4
c FFT の定義
call dfftw_plan_r2r_1d(plan1,n,a,a,FFTW_R2HC, FFTW_ESTIMATE)
call dfftw_plan_r2r_1d(plan2,n,a,a,FFTW_HC2R, FFTW_ESTIMATE)
c 0 0 23 12 の二乗の計算をする
a(1) = 12
a(2) = 23
a(3) = 0
a(4) = 0
c 実数型 FFT 正変換
call dfftw_execute(plan1)
c 各要素を二乗する
a(1)=a(1)*a(1)
a(n/2+1)=a(n/2+1)*a(n/2+1)
do i=1,n/2-1
t=a(i+1)
tt=a(n-i+1)
a(n-i+1)=2.0*t*tt
a(i+1)=(t+tt)*(t-tt)
enddo
c 実数型 FFT 逆変換
call dfftw_execute(plan2)
c 四捨五入で結果を丸める
do i=1,n
a(i)=a(i)/n
t=a(i)
a(i)=dnint(a(i))
tt=dabs(a(i)-t)
if(tt.gt.err)then
err=tt
endif
enddo
write(*,*) a(1),a(2),a(3),a(4)
c FFT 定義の開放
call dfftw_destroy_plan(plan1)
call dfftw_destroy_plan(plan2)
end
{
fftw_iodim dims[1];
dims[0].n = n;
dims[0].is = 1;
dims[0].os = 1;
forw = fftw_plan_guru_split_dft(1,dims,0,(fftwf_iodim *) 0,x,xw,x,xw,FFTW_ESTIMATE);
back = fftw_plan_guru_split_dft(1,dims,0,(fftwf_iodim *) 0,xw,x,xw,x,FFTW_ESTIMATE);
fftw_execute(forw);
fftw_execute(back);
}
で 実部、虚部が別配列の複素数変換。
real*8 a(4),work(16)
real*8 t,err,tt
integer*8 n
c 4 要素の FFT を使う
n=4
c FFT の初期化
call drffti(n,work)
c 0 0 23 12 の二乗の計算をする
a(1) = 12
a(2) = 23
a(3) = 0
a(4) = 0
c 実数型 FFT 正変換
call drfftf(n,a,work)
c 各要素を二乗する
a(1)=a(1)*a(1)
a(n)=a(n)*a(n)
do i=2,n-1,2
t=a(i)
tt=a(i+1)
a(i+1)=2.0*t*tt
a(i)=(t+tt)*(t-tt)
enddo
c 実数型 FFT 逆変換
call drfftb(n,a,work)
c 四捨五入で結果を丸める
do i=1,n
a(i)=a(i)/n
t=a(i)
a(i)=dnint(a(i))
tt=dabs(a(i)-t)
if(tt.gt.err)then
err=tt
endif
enddo
write(*,*) a(1),a(2),a(3),a(4)
end
http://www.wolfram.com/news/mersenne.ja.html >IBDWTの考え方は巨大数を無理数を底としたものにまで拡げることです. >The idea of the IBDWT is to expand giant numbers in an irrational base. これを発見しメルセンヌ素数界隈に投げ込んだことにより、Richard Crandall 氏 の名前は、GIMPS の新素数発見のプレスリリースに永遠に記載されることになった。 (Crandall氏が Mathematica でいろいろ試しながらアルゴリズムを確立して それを Cソースに起こし(luctwd.c)、それを GIMPS の GW がアセンブラでチューニング) IBDWTの具体的なアルゴリズムは 「Prime numbers: a computational perspective By Richard E. Crandall, Carl Pomerance」 に記載されています。 (Σ...とかなので自分には理解不能ですがこの本はクヌースの本を面白いと思う人にはお薦めです)
このページの内容を書くのに使った参考文献です。
数学セミナー増刊「計算の効率化とその限界」
別冊サイエンス「コンピュータ数学」
和田秀男「コンピュータと素因子分解」「数のはなし」
クヌース「準数値算法 4 算術演算」
一松信「暗号の数理」「数のエッセイ」
共立出版「素数大百科」
| P | year | discoverer | machine(時間は一つの素数候補をテストする時間) |
|---|---|---|---|
| 521 | 1952 | RAPHAEL M. ROBINSON | SWAC(1m)(Standards Western Automatic Computer) NBS(National Bureau of Standards)で作られた。1951年稼働開始。 |
| 607 | 1952 | RAPHAEL M. ROBINSON | SWAC(1.5m) |
| 1279 | 1952 | RAPHAEL M. ROBINSON | SWAC(13.5m) |
| 2203 | 1952 | RAPHAEL M. ROBINSON | SWAC(59m) |
| 2281 | 1952 | RAPHAEL M. ROBINSON | SWAC(1h6m) |
| 3217 | 1957 | HANS RIESEL(Riesel prime で有名) | BESK(Binary Electronic Sequence Calculator)(5h30m) |
| 4253 | 1961 | ALEXANDER HURWITZ | IBM-7090 360 アーキティクチャ発表以前で計算機は事務用と技術計算用に別れていた。 |
| 4423 | 1961 | ALEXANDER HURWITZ | IBM-7090(50m) |
| 9689 | 1963 | DONALD B. GILLIES | ILLIAC-II(1h23m) |
| 9941 | 1963 | DONALD B. GILLIES | ILLIAC-II(1h30m) |
| 11213 | 1963 | DONALD B. GILLIES | ILLIAC-II(2h15m) |
| 19937 | 1971 | BRYANT TUCKERMAN | IBM 360/91 汎用機が世界最速の計算機も兼ねていた時代。(35.01m) |
| 21701 | 1978 | Landon Curt Noll,Laura Nickel(now Ariel Glenn) 2人は高校生であった。 | CDC-CYBER-174(7h40m20s) |
| 23209 | 1979 | Landon Curt Noll | CDC-CYBER-174 当時、世界で3番目に高速な計算機であった。(8h39m37s) |
| 44497 | 1979 | HARRY L. NELSON,DAVID SLOWINSKI | CRAY-1(マシンサイクルが 13.5 nsec 1マシンサイクル毎に乗算と加算の結果を得られた) |
| 86243 | 1982 | DAVID SLOWINSKI | CRAY 1S(1h36m22s) |
| 110503 | 1988 | Walter N. Colquitt & Luther Welsh,Jr. | SX-2 |
| 132049 | 1983 | DAVID SLOWINSKI | CRAY X-MP(30m) |
| 216091 | 1985 | DAVID SLOWINSKI | CRAY X-MP/24 |
| 756839 | 1992 | DAVID SLOWINSKI,Paul Gage | CRAY 2 |
| 859433 | 1994 | DAVID SLOWINSKI,Paul Gage | CRAY C916 |
| 1257787 | 1996 | DAVID SLOWINSKI,Paul Gage | CRAY T94 |
メルセンヌ素数とは 2^N-1(N は自然数:素数でないとメルセンヌ素数に ならないことが知られている)の形をした素数です。メルセンヌ牧師という 人がこの素数に強い興味を持ったことからこの名がつきました。現代にお いてこの数が注目されているのはフェルマの小定理に似た、ルーカスチェ ックという素数判定法が2進法を使った計算機の上ではメルセンヌ素数 に対して有効に働くためです。 理論上はルーカスレーマチェックと同じ位に効率的なある形の素数に 対して有効な素数判定法があり、メルセンヌ素数の桁が毎回大きくなりすぎる ことなどから、計算機時代の初期には最大の素数がメルセンヌ数でないこともありましたが、 下記のプロジェクトなどによってしばらくはメルセンヌ数の天下が続くと思われます。 (実は Generalized Fermat prime の発見プログラムの方がはるかに単純)
あなたもオイラーと並んで数学史上に永遠に名をとどめてみませんか
メルセンヌ素数というのは計算機の速度が進歩すれば忘れ去られてしまう、
「RC64」とか「コンピュータがチェスで人間に勝った」とかと違って、
整数という人類が不変の興味を持って来た一分野でありあなたがそれを
発見すれば貴方の名前はしばらくは忘れ去られることはないでしょう。
パソコンメルセンヌ素数探索のメッカ
http://www.mersenne.org/
こちらの Web page では、ペンティアムの互換機を 御持ちで数週間の夜間JOB(昼間は止めておけるプログ ラムになっている) を実行して頂ける協力者の方を求 めています。 (ただし根気良くマシンを回し続けられるかなり暇な方)
あなたのコンピュータディスプレイに稲妻のように 世界最大の素数が輝く瞬間を体験してみませんか。
このなかにある ML にはその筋では有名な高 校生で当時世界最大の素数を発見したクルトノルや Cray のストロビィンスキーなども参加しています。
2004年1月現在 GIMPS での mersenne 素数探索に参加しているコンピュータは
http://mersenne.org/primenet/
によると
------- Aggregate CPU Statistics, P90 Units* -------
Last 7 Days Average Cumulative Today
from 11 Jan 2004 06h from 17 Jan 2004 06h
---------------------- ----------------------------------
Test Type CPU yr/day GFLOP/s CPU years CPU yr/day GFLOP/s
------------ ---------- ---------- ---------- ---------- ----------
Lucas-Lehmer 1001.883 12060.372 36.275 886.607 10672.712
Factoring 30.873 371.646 1.337 32.668 393.245
---------- ---------- ---------- ---------- ----------
TOTALS 1032.757 12432.018 37.612 919.275 11065.957
で、P90 換算で 30万台程度のようだ。(11Tflops!)
この能力は、次のメルセンヌ素数を探すにはそれまでのメルセンヌ素数を全て
検査する時間に等しい時間がかるといわれる、
2^20996011-1 までのルーカスチェックを1年で終えることができるようだ。
# P4 3Ghz 換算だと 3000台になります。
(*Measured in calibrated P5 90Mhz, 32.98 MFLOP units: 25658999 FPO / 0.778s using 256k FFT.)
という記述があり、P4 3Ghz マシンは P90 より 100倍程度速いのでなんと 3Gflops
出ていることになる。(FFT のサイズが大きくなるとその差は50倍程度につまる)
それに対して distributed.net の RC5-72 は
Current Information
2,951,343 Blocks were completed yesterday (0.000268% of the keyspace)
at a sustained rate of 34 Blocks/sec.
12,675,921,664,278,527 Keys were completed yesterday (0.000268% of the keyspace)
at a sustained rate of 146,712,056,300 Keys/sec.
ということで、P90 換算で 150 万台程度。
意外に GIMPS が健闘していることがわかります。
RC5 系の整数型計算と mersenne 素数の浮動小数点
計算での、P90 と P4 マシンの性能差はどうでしょうか。
http://www.orange.co.jp/~masaki/rc5/ratej.html
の RC64 のベンチマークによると
132.3 Pentium-90 の 132.3 に対して Pentium 4-2260 の 4083.3
と性能差は 30倍位です。
mersenne 素数の計算もだいたい同じ位です。
浮動小数点の性能向上の方が著しいと思ったのですが
そうでもないですね。
http://www.fftw.org/speed/ によると fft の 要素数(N) と計算時間と Mflops 値 の関係は mflops = 5 N log2(N) / (time for one FFT in microseconds) / 2 for real-data FFTs Mflops: Million floating-point operation per second (毎秒100万回の浮動小数点演算) ここに書かれている演算量は理論値で実際に計算されている浮動小数点演算の量は もう少し少ないことが多い。 256k 要素だと 1 回 の fft に 5 * 2^18 * log2(2^18) / 2 = 90 * 2^18 /2 = 12M 位の浮動小数点演算 * mersenne 素数の計算には実数型の fft が使われる。 http://mersenne.org/primenet/ によると *P90 CPU time according to Woltman/Kurowski formulation. Calibrated by benchmark P5 90Mhz, 32.98 MFLOP units: 25658999 FLOP/0.778s (256k FFT). 256k の FFT で 25M 位の計算を 0.778s で行うと 32Mflops としている。 http://www.mersenne.org/bench.htm によると ┏━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ CPU │ Iteration Times For Various Exponent Ranges and FFT sizes ┃ ┠───────┬───┬───┬───┬───┼───┬───┬───┬───┬───┬───┬────┬────┨ ┃ │ │ │ │ │6.52M │7.76M │9.04M │10.33M│12.83M│15.3M │ 17.85M │ 34.56M ┃ ┃ │Speed │Memory│ L2 │ L2 │ to │ to │ to │ to │ to │ to │ to │ to ┃ ┃ Type │(MHz) │Speed │Cache │Cache │7.76M │9.04M │10.33M│12.83M│15.3M │17.85M│ 20.4M │ 39.50M ┃ ┃ │ │ │ Size │Speed │(384K)│(448K)│(512K)│(640K)│(768K)│(896K)│(1024K) │(2048K) ┃ ┠───────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼────┼────┨ ┃ P4 │ 3060 │ │ 512 │ Full │ 0.013│ 0.016│ 0.018│ 0.023│ 0.028│ 0.034│ 0.037│ 0.068┃ ┠───────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼────┼────┨ ┃ Pentium │ 100 │ 66 │ 256 │ Bus │ 0.988│ 1.188│ 1.328│ 1.773│ 2.139│ 2.558│ 2.866│ -----┃ ┗━━━━━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━━┷━━━━┛ となっていて、ここで言う Iterration Times というのは FFT 2回分の時間らしい。(乗算の前後で 2 回 FFT を行うため) 512k での演算量は、 5 * 2^19 * log2(2^19) /2 *2 = 95 * 2^19 = 50M 回の浮動小数点演算 P100 の性能は、 50M / 1.328s = 37.7Mflops P4 3Ghz の性能は、 50M / 0.018s = 2778Mflops 2048k での演算量は、 5 * 2^21 * log2(2^21) /2 *2 = 105 * 2^21 = 210M 回の浮動小数点演算 P4 3Ghz の性能は、 210M / 0.068s = 3088Mflops となる。 The time it takes to test one exponent is the exponent being tested multiplied by the iteration time. For example, you own a 2.4 GHz Pentium 4 machine and are considering running first-time tests, if the PrimeNet server shows that the smallest available first-time exponents are around 24,000,000, find the column marked 20.18M to 25.09M and the row containing your CPU to find a per-iteration speed of 0.064 seconds. The time it takes to run one first-time test is 24,000,000 * 0.064 seconds, or 1,536,000 seconds, or (divide by 86,400) 17.8 days. 2.4Ghz P4 で P = 24,000,000 だと 20.18M から 25.09M のレンジで 一回に 0.064 sec かかるので 24,000,000 * 0.064sec で約 17.8 days で計算が終わる と書かれている。 Mlucas を実行した結果 P=20996011 の時 1280k の fft を使い 16bit/要素 1280k*16bit が 20996011 bit の倍(乗算すると桁が倍になるので)なので話があう。 ちなみに、P4 は SSE2 命令を使用すれば 1clock毎に倍精度浮動小数点演算を 2 個 発行できるため、4Ghz の clock の マシンで ピーク性能は 8Gflops である。
EB164(21164) で メルセンヌ素数探索プログラムを動かしてみる。 http://hogranch.com/mayer/README.html http://hogranch.com/mayer/bin/ALPHA_UNIX/Mlucas-2.7b-ev4-4x.tar.gz から Tru64Unix 用のバイナリをダウンロードする。 ソースも置いてあるが f90 なのでコンパイルする環境がない。 #Linux/alpha 用のバイナリは、NetBSD を簡単に crash させる。 alpha ~/Mlucas$./Mlucas-2.7b-ev4-4x looking for worktodo.ini file... no worktodo.ini file found...switching to interactive mode. Enter exponent, FFT length in K (set K = 0 for default FFT length) >216091 ← 調べたいメルセンヌ素数 16 ← FFT の要素数(エラーが出ない範囲で小さい方が速い。大き過ぎてもエラーになるようだ) Enter 'y' to run a self-test,for a full LL test > Enter index of radix set to be used for the FFT: (See file fft_radix.txt for a list of available choices; enter -1 to get the default) >0 ← 2 の倍数でない 2 の倍数でない FFT にどんな組合せを使うかの指定(0でいいようだ) Enter 'y' to enable per-iteration error checking, for no error checking >y ← y にしないとエラーチェックしないので結果が間違ってるかもしれない p is prime...proceeding with Lucas-Lehmer test... M( 216091 ): using FFT length 16K = 16384 8-byte floats. this gives an average 13.1891479492188 bits per digit INFO: Using real*16 for FFT sincos and DWT weights tables inits. Using complex FFT radices 8 8 8 16 M( 216091 ) iteration = 2000 clocks = 00:00:17.678. Res64: 4B3F667335A12495 M( 216091 ) iteration = 4000 clocks = 00:00:06.629. Res64: B265971DA23E272F .... M( 216091 ) iteration = 214000 clocks = 00:00:07.512. Res64: B5E1A392091C916B M( 216091 ) iteration = 216000 clocks = 00:00:07.435. Res64: F5AB54BCEDDF95AD M( 216091 ) is a known MERSENNE PRIME. 非常に高速である。 現在の記録の 2^20996011-1 に対して He used a 2 GHz Pentium 4 Dell Dimension PC running for 19 days to prove the number prime. だそうである。19日で1個調べられるなら流す気がおきますね。 XP1000(500Mhz 21264)で bash-2.05b$ ./Mlucas-2.7b-gen-4x looking for worktodo.ini file... no worktodo.ini file found...switching to interactive mode. Enter exponent, FFT length in K (set K = 0 for default FFT length) >20996011 1280 Enter 'y' to run a self-test, for a full LL test > Enter index of radix set to be used for the FFT: (See file fft_radix.txt for a list of available choices; enter -1 to get the default) >0 Enter 'y' to enable per-iteration error checking, for no error checking >y p is prime...proceeding with Lucas-Lehmer test... M( 20996011 ): using FFT length 1280K = 1310720 8-byte floats. this gives an average 16.0186851501465 bits per digit INFO: Using real*16 for FFT sincos and DWT weights tables inits. Using complex FFT radices 5 8 8 8 16 16 M( 20996011 ) iteration = 2000 clocks = 00:17:06.080. Res64: D36F95D9D040977B で 123日位かかる計算なので Pen 4 との比較ではだいぶ遅そう。 http://www.mersenne.org/freeware.htm にある mers.tar.gz (今は http://www.mersenne.org/various/freeware.htm) EB164(300Mhz 21164)で alpha ~/Mlucas$time ./fftlucas 216091 Dec 30 03:40:44 alpha /netbsd: osf1_getsysinfo called with unknown op=67 Dec 30 05:33:07 alpha ntpdate[983]: step time server 133.100.9.2 offset 5.872221 sec M( 216091 )P, n = 16384, fftlucas v6.50 Crandall real 302m25.074s user 301m38.702s sys 0m0.453s EB164(300Mhz 21164)で alpha ~/Mlucas$time ./mersenne1 216091 M( 216091 )P, n = 16384, mersenne1 v6.50 Kline real 121m38.889s user 121m22.696s sys 0m0.933s EB164(300Mhz 21164)で alpha ~/Mlucas$time ./mersenne2 216091 M( 216091 )P, n = 16384, mersenne2 v6.50 Kline real 135m18.800s user 135m1.832s sys 0m0.260s EB164(300Mhz 21164)で alpha ~/Mlucas$time ./Mlucas-2.7b-ev4-4x looking for worktodo.ini file... no worktodo.ini file found...switching to interactive mode. Enter exponent, FFT length in K (set K = 0 for default FFT length) >216091 12 Enter 'y' to run a self-test, for a full LL test > Enter index of radix set to be used for the FFT: (See file fft_radix.txt for a list of available choices; enter -1 to get the default) >0 Enter 'y' to enable per-iteration error checking, for no error checking >y p is prime...proceeding with Lucas-Lehmer test... M( 216091 ): using FFT length 12K = 12288 8-byte floats. this gives an average 17.5855305989583 bits per digit INFO: Using real*16 for FFT sincos and DWT weights tables inits. Using complex FFT radices 6 8 8 16 M( 216091 ) iteration = 2000 clocks = 00:00:16.583. Res64: 4B3F667335A12495 ... M( 216091 ) iteration = 214000 clocks = 00:00:10.929. Res64: B5E1A392091C916B M( 216091 ) iteration = 216000 clocks = 00:00:10.941. Res64: F5AB54BCEDDF95AD M( 216091 ) is a known MERSENNE PRIME. real 19m47.505s user 19m35.922s sys 0m0.946s XP1000(500Mhz 21264)で bash-2.05b$ time ./fftlucas 216091 M( 216091 )P, n = 16384, fftlucas v6.50 Crandall real 180m36.110s user 180m23.176s sys 0m0.191s XP1000(500Mhz 21264)で bash-2.05b$ time ./mersenne1 216091 M( 216091 )P, n = 16384, mersenne1 v6.50 Kline real 82m34.257s user 82m28.432s sys 0m0.074s XP1000(500Mhz 21264)で bash-2.05b$ time ./Mlucas-2.7b-gen-4x looking for worktodo.ini file... no worktodo.ini file found...switching to interactive mode. Enter exponent, FFT length in K (set K = 0 for default FFT length) >216091 12 Enter 'y' to run a self-test, for a full LL test > Enter index of radix set to be used for the FFT: (See file fft_radix.txt for a list of available choices; enter -1 to get the default) >0 Enter 'y' to enable per-iteration error checking, for no error checking >y p is prime...proceeding with Lucas-Lehmer test... M( 216091 ): using FFT length 12K = 12288 8-byte floats. this gives an average 17.5855305989583 bits per digit INFO: Using real*16 for FFT sincos and DWT weights tables inits. Using complex FFT radices 6 8 8 16 M( 216091 ) iteration = 2000 clocks = 00:00:14.575. Res64: 4B3F667335A12495 ... M( 216091 ) iteration = 216000 clocks = 00:00:04.617. Res64: F5AB54BCEDDF95AD M( 216091 ) is a known MERSENNE PRIME. real 8m29.231s user 8m16.145s sys 0m0.346s 手持ち最速の Pen マシンでは、 CPU: Celeron (730.90-MHz 686-class CPU) OSは、FreeBSD (このマシンの計測データは他のタスクも走っている。メインマシンなので) まずは、最速の探索プログラムも動くのでその benchmark を流す。 Your timings will be written to the results.txt file. Compare your results to other computers at http://www.mersenne.org/bench.htm That web page also contains instructions on how your results can be included. Timing 36 iterations at 256K FFT length. Best time: 72.777 ms. Timing 29 iterations at 320K FFT length. Best time: 95.155 ms. Timing 24 iterations at 384K FFT length. Best time: 114.680 ms. Timing 20 iterations at 448K FFT length. Best time: 136.719 ms. Timing 18 iterations at 512K FFT length. Best time: 153.295 ms. Timing 14 iterations at 640K FFT length. Best time: 198.322 ms. Timing 12 iterations at 768K FFT length. Best time: 241.780 ms. Timing 10 iterations at 896K FFT length. Best time: 282.542 ms. Timing 10 iterations at 1024K FFT length. Best time: 325.200 ms. Timing 10 iterations at 1280K FFT length. Best time: 416.351 ms. Timing 10 iterations at 1536K FFT length. Best time: 505.853 ms. Timing 10 iterations at 1792K FFT length. Best time: 603.524 ms. http://www.mersenne.org/bench.htm ┏━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ CPU │ Iteration Times For Various Exponent Ranges and FFT sizes ┃ ┠───────┬───┬───┬───┬───┼───┬───┬───┬───┬───┬───┬────┬────┬────┬────┬┬┨ ┃ │ │ │ │ │6.52M │7.76M │9.04M │10.33M│12.83M│15.3M │ 17.85M │ 20.4M │ 25.35M │ 30.15M ││┃ ┃ │Speed │Memory│ L2 │ L2 │ to │ to │ to │ to │ to │ to │ to │ to │ to │ to ├┼┨ ┃ Type │(MHz) │Speed │Cache │Cache │7.76M │9.04M │10.33M│12.83M│15.3M │17.85M│ 20.4M │ 25.35M │ 30.15M │ 35.1M ││┃ ┃ │ │ │ Size │Speed │(384K)│(448K)│(512K)│(640K)│(768K)│(896K)│(1024K) │(1280K) │(1536K) │(1792K) ├┼┨ ┃ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││┃ ┠───────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼────┼────┼────┼────┼┼┨ ┃ P4 │ 3060 │ │ 512 │ Full │ 0.013│ 0.016│ 0.018│ 0.023│ 0.028│ 0.034│ 0.037│ 0.053│ 0.065│ 0.081││┃ ┠───────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼────┼────┼────┼────┼┼┨ ┃ Celeron │ 733 │ 66 │ 128 │ Full │ 0.138│ 0.165│ 0.189│ 0.246│ 0.301│ 0.358│ 0.407│ 0.524│ 0.647│ 0.775││┃ ┠───────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼────┼────┼────┼────┼┼┨ ┃ Pentium │ 100 │ 66 │ 256 │ Bus │ 0.988│ 1.188│ 1.328│ 1.773│ 2.139│ 2.558│ 2.866│ 3.713│ 4.459│ 5.354││┃ ┗━━━━━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━━┷━━━━┷━━━━┷━━━━┷┷┛ とあり、大体あっている。現在最速の P4 とは10倍の開きがあるようだ。 (1万円で買ったマシンなので価格程の開きはないようだ) Celeron (730.90-MHz 686-class CPU) で テスト中に任意の P についてテストできるモードがあるので試す。 20. Help/About PrimeNet Server Your choice: 7 Exponent to test: 216091 Accept the answers above? (Y): y Starting primality test of M216091 [Dec 30 17:45] Iteration: 10000 / 216091 [4.62%]. Per iteration time: 0.002 sec. [Dec 30 17:45] Iteration: 20000 / 216091 [9.25%]. Per iteration time: 0.002 sec. [Dec 30 17:45] Iteration: 30000 / 216091 [13.88%]. Per iteration time: 0.002 sec. ... [Dec 30 17:51] Iteration: 200000 / 216091 [92.55%]. Per iteration time: 0.002 sec. [Dec 30 17:51] Iteration: 210000 / 216091 [97.18%]. Per iteration time: 0.002 sec. M216091 is prime! WY6: 8368E9FF 7分程のようだ。 Celeron (730.90-MHz 686-class CPU) で compaq ~/p$time ./fftlucas 216091 M( 216091 )P, n = 16384, fftlucas v6.50 Crandall real 135m34.955s user 130m46.688s sys 0m12.536s Celeron (730.90-MHz 686-class CPU) で compaq ~/p$time ./mersenne1 216091 M( 216091 )P, n = 16384, mersenne1 v6.50 Kline real 121m15.626s user 93m15.641s sys 0m15.756s まとめると 2^216091-1 に対するベンチマーク (感触として 2^216091-1 に対する性能と現在探査が行われている範囲との性能は比例しそうである。) XP1000(500Mhz 21264) EB164(300Mhz 21164) 730Mhz Celeron 2Ghz P4 本番プログラム - - 7m 1m以下と予想される Mlucas-2.7b-ev4-4x 8m 20m - fftlucas 180m 302m 135m mersenne1 82m 121m 121m 現在の中古価格 5万円 1万円 1万円 10万円 Mlucas-2.7b-ev4-4x は、Pen 用の本番プログラムと比較してチューニングの度合 としてはがんばっていそうである。alpha は、Pen と比較してこの問題に 向いていないという結論が出てしまいそう。 http://www.ocrat.com/mersenne/ にある mayerE25C3.tar.gz を動かす。 xp1000 $./lucas_mayer no restart file found...looking for range file... no range file found...switching to interactive mode. Enter p,n (set n=0 for default FFT length) >11213,0 Enter "y" to run a self-test, for a full LL test > p is prime...proceeding with Lucas-Lehmer test... using an FFT length of 512 this gives an average 21.900391 bits per digit calculating sin/cos values...done M( 11213 ) iteration = 2000 clocks = 00:00:00.000 M( 11213 ) iteration = 4000 clocks = 00:00:01.000 M( 11213 ) iteration = 6000 clocks = 00:00:00.000 M( 11213 ) iteration = 8000 clocks = 00:00:01.000 M( 11213 ) iteration = 10000 clocks = 00:00:01.000 M( 11213 ) is a known MERSENNE PRIME. これもなかなか高速である。 GIMPS Source Code Timings Page http://hogranch.com/mayer/gimps_timings.html を見ると Glucas というプログラムがあるようだ。 GLUCAS - Yet Another FFT http://glucas.sourceforge.net/ からソースをダウンロードして、./configure make する。 glucas.que というファイルを作って中に 調べたい P を入れる。 216091 で試してみると xp1000 glucas-2.9.0$time ./Glucas real 9m56.624s user 9m52.195s sys 0m0.079s glucas.out に結果が入る。 Iter. 200000 ( 92.55%), Err= 0.000, 26.87 user 99% CPU (0.003 sec/iter). M216091. Saved file at iteration 200704. Res64: F4E92A3E32F77E9F. M216091. Saved file at iteration 204800. Res64: 78897F6C7A3E982E. M216091. Saved file at iteration 208896. Res64: 1007948E422A60B9. Iter. 210000 ( 97.18%), Err= 0.000, 26.88 user 99% CPU (0.003 sec/iter). M216091. Saved file at iteration 212992. Res64: 240FD3A839CB978D. [Wed Feb 4 05:08:51 2004] M216091 is a known Mersenne prime! Terminated all the queued job in file: glucas.que. P=20996011 で動かしてみる。 [Wed Feb 4 05:26:54 2004] Going to work with exponent 20996011 Starting from iteration 1. Exponent 20996011. M20996011. Saved file at iteration 4096. Res64: BFA31B6520E49912. M20996011. Saved file at iteration 8192. Res64: 141E6DE86BB2DD30. Iter. 10000 ( 0.05%), Err= 0.148, 5128.38 user 100% CPU (0.513 sec/iter). M20996011. Saved file at iteration 12288. Res64: 59F8E563958FF7CC. M20996011. Saved file at iteration 16384. Res64: 239A8FBAC9CE49E6. Iter. 20000 ( 0.10%), Err= 0.141, 5128.05 user 100% CPU (0.513 sec/iter). alpha で動作する ソース付きとしてはこれが一番高速である。 http://mersenne.org/primenet/status.txt にステータスのページがある prime fact current days exponent bits iteration run / to go / exp date updated date assigned a -------- -- ---- --------- ----------------- --------------- --------------- - 21039677 67 8816895 95.0 65.4 77.4 24-Jan-04 15:54 01-Nov-03 05:02 S が私のパソコンで実行されている。 67bit まで試行除算されている。
これも mers.tar.gz に含まれる試行除算のプログラム (今は http://www.mersenne.org/various/freeware.htm) mersfacgmp /pkgsrc/devel/gmp がインストールされている必要がある。 xp1000 $./mersfacgmp 12000257 M( 12000257 )C: 96002057 M( 12000257 )J: 24000515 96002057 M( 12000257 )H: 96002057 216091 M( 216091 )J: 432183 42485219329 M( 216091 )U: 42485219329 のように実行する。割り切れた場合は、C: が表示される。 J: が除算を試行した値の最小値と最大値 xp1000 $./mersfacgmp -e42 216091 M( 216091 )J: 432183 4418462810113 M( 216091 )U: 4418462810113 試行する桁を増やす場合は、-e で指定する。(log みたい) #何故か FreeBSD/i386 では上手く動かなかった。 mersfaclip コンパイルには、 http://www.und.edu/org/crypto/crypto/numbers/programs/freelip/freelip_1.1.tar.gz が必要。 xp1000 $time ./mersfaclip -e45 < 216091 M( 216091 )J: 432183 35220246822913 M( 216091 )U: 35220246822913 real 1m23.136s user 1m23.032s sys 0m0.005s compaq $time ./mersfaclip -e45 < 216091 M( 216091 )J: 432183 35220246822913 M( 216091 ): 35220246822913 real 1m37.294s user 1m36.804s sys 0m0.032s このプログラムは FreeBSD/i386 でも動いた。 mersfacgmp を使って 2^20996011-1 〜 2^21012671-1 の 1000個のメルセンヌ数について素因数を調べてみる。 P1000 に p を格納し xp1000 $./mersfacgmp -e 55 < P1000 > D1000 この範囲で素因数が見付かったのが 539個 素因数の(10進での)桁数毎の個数を見てみると 8桁 33 9桁 98 10桁 91 11桁 74 12桁 67 13桁 82 14桁 38 15桁 38 16桁 37 17桁 9 となった。 http://hogranch.com/mayer/README.html にある Mfactor.c.gz も試行除算プログラム cc -O4 Mfacytor.c でコンパイルして P=21008633 に対して実行してみると xp1000 Mlucas$time ./a.out 21008633 0 1271201920312151 # Mersenne factorer. Author: Peter L. Montgomery, pmontgom@cwi.nl # $Id: Mfactor.c,v 1.13 1997/05/19 05:34:22 wedgingt Exp $ # Compiled by GCC on unknown architecture under unknown OS. # ARITHMETIC_MODEL = ARITHMETIC_FP64 # NUM_SIEVING_PRIME = 34567, SIEVE_LENGTH_BITS = 589824 # SIEVE_STEP_BIT = 840 # TRYQ_BLOCKING = 3, USING_ASSEMBLY = 0, USING_POPULATION_COUNT = 0 # VECTOR = 0, SHORT_VECTOR_LENGTH = 20 # Type sieving_prime_t has 32 bits. # Type wsieve_t has 64 bits, of which all 64 are used. # Type natural_t is signed and has 64 bits. # Floating point mantissa has 53 significant bits. # QBITSMAX = 53 # # Invoked as ./a.out 21008633 0 1271201920312151 # Running on xp1000 at Wed Feb 4 12:52:18 2004 # No history file specified (use -h parameter). # Results will be written to standard output only. # # p = 21008633. Searching q in [1, 1271201920312151] # The isieve loop in tryp sieves an interval of length # 10408772598497280 = 1.041e+16 in NSIEVE = 96 pieces. # It will need 0.12 passes to search from 1 to 1271201920312151. # Your SIEVE_STEP_BIT (or SIEVE_LENGTH_BITS) seems high for your search limits. # 34567-th sieving prime is 409639. 25593 are below SIEVE_LENGTH_BITS/2, # 8974 more below SIEVE_LENGTH_BITS, 0 above. M( 21008633 )C: 1271201920312151 # xp1000 @ Wed Feb 4 12:52:22 2004 # 1323070 values of q tried out of 6915264 sieved. # 80.87% of potential q's (mod 840*p) were eliminated by sieving. M( 21008633 )U: 1271201920312151 # xp1000 @ Wed Feb 4 12:52:22 2004 real 0m4.161s user 0m4.150s sys 0m0.008s となる。 mersfacgmp で同じ P で実行すると xp1000 mers$time ./mersfacgmp -e50 < 21008633 M( 21008633 )J: 42017267 1127617031503873 M( 21008633 )U: 1127617031503873 real 0m19.736s user 0m19.725s sys 0m0.007s となる Mfactor の方が数倍高速である。
http://www.mersenne.org/gimps/lucdwt.c
(今は http://mersenneforum.org/gimps/lucdwt.c)
GIMPS にある一番単純なルーカスチェックのプログラム
Richard E. Crandall氏がこれを GIMPS に提供し、
Prime95 はこれをチューングしたようです。
$ ./a.out 11213 512 0 1
.........
11209 maxerr: 0.078125
11210 maxerr: 0.085938
11211 maxerr: 0.000000
11213 0
0 になればメルセンヌ素数。
(引数は、テストするp、FFT要素数、途中で停止する場合のくり返し数、くり返し毎に print するか)
lucdwt.c:
880 for(j=1;j< last;j++)
881 {
882 err = lucas_square(x,n,errflag);
883 if (errflag)
884 {
885 printf("%ld maxerr: %f\n",j,err);
886 fflush(stdout);
887 }
888 x[0] -= 2.0;
889 }
メインループ二乗するたび -2 してます。
415 void
416 squareg(
417 double *x,
418 int size
419 )
420 {
421 fft_real_to_hermitian(x, size);
422 square_hermitian(x, size);
423 fftinv_hermitian_to_real(x, size);
424 }
FFT して各要素を二乗して逆FFT
mersenne 素数以外に同じような効率で素数検査できる数に Generalized Fermat Prime
がある。
b^N+1 ( N は 2^n ) という形の数。
http://primes.utm.edu/primes/lists/all.txt
にある
順位 桁数 発見年 性質
498 1287484^16384+1 100103 g197 2001 Generalized Fermat
1198 2^216091-1 65050 S 1985 Mersenne 31
1199 87077894^8192+1 65044 g303 2003 Generalized Fermat
4309 1430330^8192+1 50426 g162 2001 Generalized Fermat
4744 764898^8192+1 48199 g232 2001 Generalized Fermat
4995 504216^8192+1 46716 g6 2000 Generalized Fermat
をテストに使う。
http://perso.wanadoo.fr/yves.gallot/primes/download.html
には、ソース付きのプログラムがある。
genefer80.gz: binary for Linux of the 80-bit version of the program.
は、バイナリのみだが x86 の 80bit版の命令を使って 探査する桁数によっては
高速だという。
Linux 上 Celern 533Mhz で
$ time ./genefer80
GeneFer 1.3 (80-bit x86-ASM) Copyright (C) 2001-2003, Yves GALLOT
A program for finding large probable generalized Fermat primes.
Usage: GeneFer -b run bench
GeneFer -t run test
GeneFer <filename> test <filename>
GeneFer use interactive mode
1. bench
2. test
3. normal
N: 8192
b: 504216
504216^8192+1 is a probable prime. (err = 1.53e-05)
real 16m35.914s
user 16m17.690s
sys 0m0.010s
genefer64.gz : binary for Linux.
は通常の 倍精度を使った版。
Linux 上 Celern 533Mhz で
[msft@funaki tmp]$ time ./genefer64
GeneFer 1.3 (x86-ASM) Copyright (C) 2001-2003, Yves GALLOT
A program for finding large probable generalized Fermat primes.
Usage: GeneFer -b run bench
GeneFer -t run test
GeneFer <filename> test <filename>
GeneFer use interactive mode
1. bench
2. test
3. normal
N: 8192
b: 504216
504216^8192+1 is a probable prime. (err = 9.59e-03)
real 8m57.813s
user 8m49.060s
sys 0m0.000s
こちらの方が速い。まだサイズが小さいのかもしれない。
ソース版の genefer.c を使ってみる。
Linux 上 Celern 533Mhz で
$ cc -O3 ./genefer.c -lm
$ time ./a.out
GeneFer 1.3 (standard) Copyright (C) 2001-2002, Yves GALLOT
A program for finding large probable generalized Fermat primes.
Usage: GeneFer -b run bench
GeneFer -t run test
GeneFer <filename> test <filename>
GeneFer use interactive mode
1. bench
2. test
3. normal
N: 8192
b: 504216
504216^8192+1 is a probable prime. (err = 2.16e-02)
real 18m43.390s
user 18m27.520s
sys 0m0.040s
alpha 21264 500Mhz/XP1000/NetBSD/gcc での結果
N: 8192
b: 504216
504216^8192+1 is a probable prime. (err = 2.73e-02)
real 4m28.451s
user 4m19.482s
sys 0m0.006s
なかなか良い結果。
linux/Celeron 533Mhz での測定結果(user time)
N | genefer64 | genefer80 | mprime(GMIPS)
------------------------+-----------------------+-----------------------+---------------------
504216^8192+1 | 8m49.060s | 16m17.690s |
764898^8192+1 | 10m9.740s | |
2^216091-1 | --- | --- | 12m28.510s
87977894^8192+1 | 12m15.350s | |
1287484^16384+1 | 32m52.700s | |
87977894^8192+1 と 2^216091-1 はほぼ同じ桁数だが
計算時間も ほぼ同じでこのプログラムが良く最適化されていることがわかる。
(本当は P4 で比較しないと意味ないけど)
Athlon Optimized GFN Deep Sieve
には、Windows上で動作する GFN 用のふるいプログラムがある。
通常の Windows 版は、US Yahoo のフォーラムのみで配布されているようだ。
http://www.utm.edu/research/primes/programs/gallot/
には Proth.exe がある。
Proth's Theorem (1878): Let N = k^(2^n)+1 with 2^n > k.
If there is an integer a such that
a^(N-1)/2 = -1 (mod N),
then N is prime.
N = k^(2^n)+1 で 2**n > k の時 ヤコビ記号[a,N] = -1
a^(N-1)/2 = -1 (mod N) なる a が存在すれば N は素数
という Proth's が証明した定理に基づいて素数を探索するプログラム。
(実際には、このタイプ以外の素数も探索できるように拡張されている)
http://netnews.gotdns.org/WallStreet/6351/txt/gfn.f
自分でも作ってみた。
-- P4 でも測定した
Freebsd/P4 1.4GMhz での測定結果(user time)
N | genefer64 | genefer80 | mprime(GMIPS)
------------------------+-----------------------+-----------------------+---------------------
504216^8192+1 | 1m31.258s | 4m54.811s |
764898^8192+1 | 1m34.290s | |
2^216091-1 | --- | --- | 1m58.912s
87977894^8192+1 | 2m7.615s | |
2^756839-1 | --- | --- | 31m28.277s
10021136^32768+1 | 37m56.906s(ERR) | |
mersenne 素数を除くと k.2^n-1 の形の素数が現在は、一番高速に探索できるようだ。
http://www.utm.edu/research/primes/programs/NewPGen/
より linux 用の newpgen をダウンロードする。
$ ./snewpgen
NewPGen 2.82 - Use Control-C to manually stop the current sieving.
What do you want to do now ?
0 : To create a new file.
1 : To continue sieving an old file.
2 : To change one or several option(s).
3 : To get a service.
4 : To get some help.
5 : To exit from this program.
Please, enter your choice (0) : 0
Verify results ? (n) :
Creating a new file ; Output file name = Newpgen ← 出力ファイル
Using primorial mode ? (n) :
What type of sieve do you want to do ?
The available types of sieve are :
0 : k.b^n+1
1 : k.b^n-1
2 : Twin: k.b^n
3 : SG: k.b^n-1 & 2k.b^n-1
4 : CC: k.b^n+1 & 2k.b^n+1
5 : BiTwin: k.b^n & 2k.b^n
6 : Twin/SG: k.b^n & 2k.b^n-1
7 : Twin/CC: k.b^n & 2k.b^n+1
8 : LP: k.b^n & k.b^(n-1)+1 & k.b^(n+1)+1
9 : LM: k.b^n & k.b^(n-1)-1 & k.b^(n+1)-1
10 : CC 1st kind
11 : CC 2nd kind
12 : BiTwin
13 : AP: b^n+2k-1 (-2 if b is odd)
14 : 3-tuple: k.b^n & k.b^n+5
15 : 4-tuple: k.b^n, +5, +7
16 : k.b^n+1 with k fixed
17 : k.b^n-1 with k fixed
18 : SG: k.b^n+1 & 2k.b^n+3
19 : b^n+k with k fixed
20 : b^n-k with k fixed
Please, enter your choice (0) : 17 ← k.b^n-1 の k 固定を選択
Base = 2
k = 1192 ← 1002 〜 2000 位の値を選択(小さい方が高速だが小さい値は探索が進んでいる)
nmin = 170000 ← TOP5000 に最低ランクインする n の値
nmax = 999999 ← 最大値
Type : k.b^n-1 with k fixed
Are you ready to start sieving ? (y) :
CPU capabilities: CMOV: Supported. SSE2: Supported.
Using bitmap : allocating 101.3Kb of RAM...
...succeeded
830000 candidates
Sieving numbers with 51179 to 301033 decimal digits
ふるいが開始される。60秒毎に新しい値がふるえる位の範囲でよさそう。
http://pagesperso-orange.fr/jean.penne/index2.html
から llr をダウンロードする。
$ ./SLLRP4 -m
Main Menu
1. Test/Input Data
2. Test/Continue
3. Test/Exit
4. Options/CPU
5. Options/Preferences
6. Advanced/Priority
7. Help/About
Your choice: 1
Input file (from NewPgen): : Newpgen
Output file (Results): : Results
Line number (1): 1
Accept the answers above? (Y): y
Main Menu
1. Test/Input Data
2. Test/Continue
3. Test/Exit
4. Options/CPU
5. Options/Preferences
6. Advanced/Priority
7. Help/About
Your choice: 3
$ ./SLLRP4 -b
で探索が開始される。
ここで残った値もまだ素数に確定したわけではないので
http://www.utm.edu/research/primes/programs/gallot/
の proth.exe で最後の確認をする。
http://www.mycgiserver.com/~primesearch/mainmenu.jsp
に k= 251-1001 の範囲の探査をしているプロジェクトがある。
| P | cpu time | sec/ier | machine | CPU | clock | program | OS,compiler,others | name | date |
|---|---|---|---|---|---|---|---|---|---|
| 33,333,333 | N/A | 0.012 | GTX260 | Gforce | 1.4Ghz | MACLucasFFTW | linux | msft | 2009.12.1 |
| 32,582,657 | N/A | 0.084 | PLAYSTATION3 | IBM Cell | 3.2Ghz | MACLucasFFTW | linux | msft | 2009.8.11 |
| 20,996,011 | N/A | 0.091 | AOPEN AK86-L | Athlon64 | 2087Mhz | mprime | Vine linux | msft | 2005.1.11 |
| 20,996,011 | N/A | 0.097 | IBM NetVista M41 Slim(6844-32J) | P4 | 1.6Ghz | mprime | Vine linux 2.4.22 | msft | 2004.7.3 |
| 20,996,011 | N/A | 0.507 | Compaq XP1000 | alpha 21264 | 500Mhz | Glucas | Netbsd 1.6.1 gcc 2.95.3 | msft | 2004.2.8 |
| 20,996,011 | N/A | 0.644 | Samsung UP1100 | alpha 21264 | 600Mhz | Mlucas-2.7b-gen | RedHat7 | msft | 2004.4.18 |
| 20,708,011 | N/A | 0.049 | GIGABYTE | P4 Prescott | 2.8Ghz | Prime95 | Win2000 | msft | 2004.3.25 |
| 20,708,011 | N/A | 0.049 | GIGABYTE | P4 Prescott | 2.8Ghz | mprime | FreeBSD 5.2-RELEASE | msft | 2004.3.26 |
| 20,708,011 | N/A | 0.097 | IBM NetVista | P4 | 1.6Ghz | mprime | Vine linux 2.4.22 | msft | 2004.7.3 |
| 20,708,011 | N/A | 0.167 | GIGABYTE | P4 Prescott | 2.8Ghz | Glucas | Win2000 gcc 3.3.1 | msft | 2004.3.25 |
| 20,708,011 | N/A | 0.283 | IBM NetVista | P4 | 1.6Ghz | Glucas | Vine linux 2.4.22 gcc 2.95.3 | msft | 2004.7.3 |
| 2,976,221 | N/A | 0.010 | IBM NetVista | P4 | 1.6Ghz | mprime | FreeBSD 6.3-RELEASE | msft | 2008.3.19 |
| 2,976,221 | N/A | 0.011 | IBM NetVista | P4 | 1.6Ghz | mprime | Vine linux 2.4.22 | msft | 2004.7.3 |
| 2,976,221 | N/A | 0.027 | GIGABYTE | P4 Prescott | 2.8Ghz | Glucas | Win2000 gcc 3.3.1 | msft | 2004.3.25 |
| 2,976,221 | N/A | 0.032 | Samsung UP1100 | alpha 21264 | 600Mhz | Glucas | RedHat7 gcc 3.3.3 | msft | 2004.4.18 |
| 2,976,221 | N/A | 0.034 | Compaq XP1000 | alpha 21264 | 500Mhz | Glucas | RedHat7 ccc | msft | 2004.2.22 |
| 2,976,221 | 1d13h18m | 0.044 | Compaq XP1000 | alpha 21264 | 500Mhz | Glucas | Netbsd 1.6.1 gcc 2.95.3 | msft | 2004.2.8 |
| 2,976,221 | 1d22h7m | 0.047 | Compaq | Celeron | 730Mhz | mprime | FreeBSD 4.7-RELEASE | msft | 2004.2.8 |
| 2,976,221 | N/A | 0.053 | Compaq XP1000 | alpha 21264 | 500Mhz | Mlucas-2.7b-gen | RedHat7 | msft | 2004.4.18 |
| 2,976,221 | N/A | 0.064 | Samsung UP1100 | alpha 21264 | 600Mhz | Mlucas-2.7b-gen | RedHat7 | msft | 2004.4.18 |
| 2,976,221 | N/A | 0.068 | Compaq | Celeron | 730Mhz | Glucas | FreeBSD 4.7-RELEASE gcc 2.95.4 | msft | 2004.3.25 |
| 2,976,221 | N/A | 0.069 | Apple | PowerPC G4 | 800Mhz | Glucas | Mac OS X 10.2.8 gcc 3.1 | msft | 2004.3.11 |
| 2,976,221 | N/A | 0.079 | Intel | Celeron | 533Mhz | mprime | Vine linux 2.4.22 | msft | 2004.4.06 |
| 2,976,221 | N/A | 0.103 | Intel | Celeron | 533Mhz | Glucas | Vine linux 2.4.22 gcc 2.95.3 | msft | 2004.4.06 |
| 2,976,221 | 3d21h45m | 0.113 | DEC EB164 | alpha 21164 | 300Mhz | Glucas | Netbsd 1.6.1 gcc 2.95.3 | msft | 2004.2.10 |
| 2,976,221 | 26d15h51m | 0.840 | Compaq | Pentium/P54C | 120Mhz | Glucas | FreeBSD 4.8-RELEASE gcc 2.95.4 | msft | 2004.3.9 |
| 216,091 | 2m9s | 0.001 | AOPEN AK86-L | Athlon64 | 2.0Ghz | Glucas | Gentoo linux gcc 3.4.3 | msft | 2004.12.13 |
| 216,091 | 2m40s | N/A | PLAYSTATION3 | IBM Cell | 3.2Ghz | MACLucasFFTW | linux | msft | 2009.8.11 |
| 216,091 | 5m28s | N/A | IBM NetVista | P4 | 1.6Ghz | Glucas | Vine linux 2.4.26 gcc 3.3.2 | msft | 2004.12.13 |
| 216,091 | 6m9s | 0.002 | GIGABYTE | P4 Prescott | 2.8Ghz | Glucas | Win2000 gcc 3.3.1 | msft | 2004.3.11 |
| 216,091 | 11m21s | 0.003 | Apple | PowerPC G4 | 800Mhz | Glucas | Mac OS X 10.2.8 gcc 3.1 | msft | 2004.3.11 |
| 216,091 | 1h4m | 0.017 | Cyrix | VIA C3 | 533Mhz | Glucas | Win2000 gcc 3.3.1 | msft | 2004.3.11 |
| 216,091 | 3h | 0.046 | Compaq | Pentium/P54C | 120Mhz | Glucas | FreeBSD 4.8-RELEASE gcc 2.95.4 | msft | 2004.3.11 |
Riesel prime とは、 k*2n-1, odd k > 1 という形の素数です。 この形の素数を探すには、他の方のプロジェクトに参加するか個人で探す ことになります。ここでは個人で探す場合について記述します。 過去に探索された範囲、および範囲の予約は、 http://karbon.npage.de/k_%3C_300_15525520.html http://www.myjavaserver.com/~primesearch/ http://www.15k.org/ ですが、既知素数のリスト http://primes.utm.edu/primes/download.php を見ると上のwwwページではまだ未探索、未発見とされている Riesel prime も沢山あることがわかります。 そこで確実に未探索の領域となると k の大きな値を探すことになりますが、 探索ソフトの llr は k が小さい方が高速(特に k>511) という特徴があります。 http://www.mersenneforum.org/index.php でも、いろいろな素数探索の宣言がされているので目を通すと良いようです。
Prime95 に楕円曲線法による素因数分解機能が追加されフェルマー数とメルセンヌ数 の分解プロジェクトもはじまりました。(Prim95 のメニューから選べます) 乗算にアセンブラによる FFT と IBDWT を用いており従来よりかなり高速になって います。新素因数の発見が期待されます。
srsieve は、newpgen より速いらしい篩いソフトです。 ../../../www.geocities.com/g_w_reynolds/srsieve k*2^n-1 で k 固定の場合を篩います。 $./srsieve -a -n 3e5 -N 1e6 -P 1e9 "196608*2^n-1" 196608*2^n-1 で 300000 < n < 1000000 の範囲を 1e9 まで篩う。 篩いは、1e9 まではやります。 (sr2sieve が、1e9 以降からしか開始できないため) 結果は、 $head sr_2.abcd ABCD 196608*2^$a-1 [300014] // Sieved to 1000000000 with srsieve 5 25 4 39 20 3 20 22 7 という abc 形式というファイルで得られます。 $./srfile -g sr_2.abcd で Newpgen 出力フォーマットへ変換できます。 次により高速な sr2sieve で篩いを継続します。 $./sr2sieve --sse2 -i sr_2.abcd -p 1e9 -P 20e9 19978878169 | 196608*2^412147-1 19996720703 | 196608*2^314314-1 p=19996789363, 620774 p/sec, 8144 factors, 100.0% done, 3 sec/factor sr2sieve 1.7.10 stopped: at p=20000000000 because range is complete. Found factors for 8144 terms in 31803.538 sec. (expected about 8157.53) real 530m3.550s user 262m2.443s sys 0m4.677s 1e9 から 20e9 までの篩いを指示しています。 $ ls -l total 1476 -rw-r--r-- 1 msft others 6831 Apr 19 23:57 README -rw-r--r-- 1 msft others 1726 Apr 19 23:57 README-threads -rw-r--r-- 1 msft others 317570 Apr 20 09:34 factors.txt -rwxr-xr-x 1 msft others 84840 Apr 19 23:57 sr2sieve -rw-r--r-- 1 msft others 44790 Apr 19 23:57 sr2sieve-1.7.10-linux-x86.tar.gz -rw-r--r-- 1 msft others 3933 Apr 20 09:34 sr2sieve.log -rw-r--r-- 1 msft others 0 Apr 19 23:57 sr2work.txt -rw-r--r-- 1 msft others 156889 Apr 19 23:57 sr_2.abcd -rwxr-xr-x 1 msft others 28508 Apr 20 00:03 srfile -rw-r--r-- 1 msft others 804976 Apr 19 23:57 srsieve.out 篩いの結果は factors.txt というファイルに篩われた数が入る形で得られます。 $./srfile --known-factors factors.txt sr_2.abcd とすると sr_2.abcd から factors.txt にある数を除いて srsieve.out に出力します。 $./srfile -g srsieve.out $cat -n t17_b2_k196608.npg |tail 56436 196608 999924 56437 196608 999947 56438 196608 999950 56439 196608 999951 56440 196608 999962 56441 196608 999967 56442 196608 999972 56443 196608 999980 56444 196608 999987 56445 196608 999994 -g オプションで newpgen の形式に変換します。 $ ./srfile -a t17_b2_k196608.npg srfile 0.6.10 -- A file utility for srsieve. Read 56444 terms for 1 sequence from NewPGen format file `t17_b2_k196608.npg'. Wrote 56444 terms for 1 sequence to ABCD format file `sr_2.abcd'. -a オプションで篩いの結果を除いた abc ファイルが作成されます。 これを入力にして sr2sieve を継続できます。 $sr2sieve 1.7.10 -- A sieve for multiple sequences k*b^n+/-1 and b^n+/-k. Reading `sr_2.abcd' ... WARNING: --pmin=20000000000 from command line overrides pmin=1000000000 from `sr_2.abcd' Read 64588 terms for 1 sequence from ABCD format file `sr_2.abcd'. Split 1 base 2 sequence into 34 base 2^60 subsequences. Expecting to find factors for about 1085.54 terms in this range. sr2sieve 1.7.10 started: 300014 <= n <= 999994, 20000000000 <= p <= 30000000000
フェルマーテストなどには全て合格するが、素数検査は桁数が大きすぎる などで実行できない数を概素数という。 PRP Records Probable Primes Top 10000 に1万桁以上の概素数が集められて更新されている。 最大の概素数は、 (2^1148729+2^574365+1)/5 で 345802桁である。(2008/5 現在) llr を使って Gaussian Mersenne norm(これは素数) を探索する 過程で発見されたようだ。 素数のレコードと比較すると小さく、最速のパソコンを数台お持ちなら 個人でも更新可能と思われる。 ただ、素数性が証明できる数ではいけないので、流通している高速なプログラムの 種類から、llr で 2^n+3 を探すと良いかもしれない。
http://www2.cc.niigata-u.ac.jp/~takeuchi/tbasic/BackGround/Euler.html フェルマーの小定理を一般化したオイラーの定理は強力である。 この定理は、約数についてフェルマーテストのような素数性検査を可能にする。 例えば、メルセンヌ数が小さな素数で割れる場合に残った数についての素数性検査 をメルセンヌ数に対するフェルマーテストのプログラムのループの回数だけを 変えることで可能にする。 何故、約数に直接フェルマーテストを行わないかというと(例えば pfgw では可能 である)、約数では剰余の計算が大変になる、メルセンヌ数にはもともと高速な フェルマーテストプログラムが存在するからである。 ただし、素数性を証明はできないので概素数となる。
http://www.eff.org/awards/coop
Through the EFF Cooperative Computing Awards, EFF will confer prizes of:
* $50,000 to the first individual or group who discovers a prime number with at least 1,000,000 decimal digits
* $100,000 to the first individual or group who discovers a prime number with at least 10,000,000 decimal digits
* $150,000 to the first individual or group who discovers a prime number with at least 100,000,000 decimal digits
* $250,000 to the first individual or group who discovers a prime number with at least 1,000,000,000 decimal digits
まだ賞金は続きます。がんばりましょう。
不確定性原理を応用した量子コンピュータというものが発明され、実際に 15 を 3 と 5 に素因数分解することに成功したようです。 そういえば、ファイマンさんが仁科財団の招きで来日して「計算のエネル ギーは何処まで減らせるか」という題で講演した時に、日本の物理学者達は 講演内容そっちのけでファイマンさんの過去の業績の質問してました。