SFMT ジャンプ

English Version
dSFMT ジャンプ
SFMTのページ

目次

SFMT ジャンプ機能について

ジャンプ機能を使うと、SFMTのある内部状態からNステップ後の状態を計算することが 出来ます。これはSFMTの32ビット乱数生成を4N回呼び出すのと同じことですが、 Nが大きい場合、乱数生成よりずっと速くNステップ後の状態に移ることができます。 ジャンプ機能の典型的な使用法は、SFMTによって生成される(長い)周期の中で、 互いに重ならないという保証のある複数の部分列を取得することです。

ジャンプを実行するには二つのステップがあります。ジャンプ多項式の計算と内部状態の 変更です。

ステップ1:ジャンプ多項式の計算

線形疑似乱数生成器の特性多項式ϕとジャンプステップNから 以下の式によってジャンプ多項式ψを計算することができます。

ψ = XN mod ϕ.

式から分かるように、ジャンプ多項式ψの次数は、ジャンプステップN に関わらず、特性多項式ϕの次数より小さくなります。
メルセンヌ指数がMEXPのSFMTの特性多項式は、独自の文字列形式で、 'characteristic.MEXP.txt' ファイルに保存されています。 このファイルはジャンプ機能のアーカイブファイルに含まれています。
make によって作られる実行可能ファイル 'calc-jump'を使って、 コマンドラインからジャンプ多項式を計算することができます。 使用法は以下のとおりです。

./calc-jump jump-step characteristic-file [no.]
    jump-step: a number between zero and 2^{SFMT_MEXP}-1.
               large decimal number is allowed.
    characteristic-file: one of characteristic.{SFMT_MEXP}.txt file
    [no.]: shows which characteristic polynomial in
           the file should be used. 0 is used if omitted.
           this is used for files in params directory.

jump-stepは十進数で指定してください。大きな数を指定することが出来ます。 no. は、params ディレクトリにある characteristic.{SFMT_MEXP}.txt ファイルを使用する時に、指定してください。
C++ の関数 'sfmt::calc_jump' を使ってジャンプ多項式を計算することも できます。この関数は 'SFMT-calc-jump.hpp' ファイルの中で定義されています。

ジャンプ多項式の計算にはVictor Shoup教授の NTL: A Library for doing Number Theory が必要です。
また、ジャンプ多項式の計算にはSFMTの内部状態は必要ありませんし、 特性多項式の格納されたファイル名以外はメルセンヌ指数にも依存しません。

ステップ2:SFMTの内部状態をジャンプ後の状態に変更する

このステップは、SFMTのメルセンヌ指数に依存します。 ジャンプ多項式の計算に使用した特性多項式の次数と同じメルセンヌ指数を 必ず使用してください。
C言語で書かれたSFMT_jump関数がこのステップを実行します。 この関数は、SFMT-jump.hの中で宣言されています。 この関数のコンパイルには、SFMT バージョン1.4 が必要です。

ダウンロード

SFMTJump-src-0.1.tar.gz
SFMTJump-src-0.1.zip

インストール、コンパイル、テスト

Jump プログラムは単独ではコンパイルできません。SFMT 1.4 のソースファイルが 必要です。

  1. NTLをインストールしていなければ インストールする。
  2. アーカイブファイルを解凍します。
  3. 出来たディレクトリ(SFMTJump-src-xxx)の中のjumpディレクトリを SFMTのディクレクトリにコピーします。
  4. SFMT-src-1.4
       +---html
       +---params
       +---jump
    
  5. コピーしたjumpディレクトリにcd します。
  6. NTLのインストール時にgmp か gf2x を使用した場合は、Makefile の 以下の行のどちらかのコメントを外す必要があります。
  7. #LIBGF2X = -lgf2x
    #LIBGMP = -lgmp
    
  8. make を実行します
  9. make all
    make check
    
  10. make check の結果 OK と表示されればテストは成功です

make check で作られた test-jump-MXXX ファイルは、-s を指定して実行するとジャンプ多項式の計算時間とジャンプの実行時間を表示します。

$ ./test-jump-M19937 -s
mexp 19937 jump 10^04 steps calc_jump: 0.806ms
mexp 19937 jump 10^04 steps SFMT_jump: 0.319ms
mexp 19937 jump 10^06 steps calc_jump: 3.562ms
mexp 19937 jump 10^06 steps SFMT_jump: 3.248ms
mexp 19937 jump 10^08 steps calc_jump: 6.480ms
mexp 19937 jump 10^08 steps SFMT_jump: 3.275ms
mexp 19937 jump 10^10 steps calc_jump: 9.385ms
mexp 19937 jump 10^10 steps SFMT_jump: 3.267ms
mexp 19937 jump 10^12 steps calc_jump:12.720ms
mexp 19937 jump 10^12 steps SFMT_jump: 3.273ms
mexp 19937 jump 10^14 steps calc_jump:15.429ms
mexp 19937 jump 10^14 steps SFMT_jump: 3.280ms
mexp 19937 jump 10^16 steps calc_jump:18.377ms
mexp 19937 jump 10^16 steps SFMT_jump: 3.301ms
mexp 19937 jump 10^18 steps calc_jump:21.416ms
mexp 19937 jump 10^18 steps SFMT_jump: 3.297ms
mexp 19937 jump 10^20 steps calc_jump:24.440ms
mexp 19937 jump 10^20 steps SFMT_jump: 3.233ms
mexp 19937 jump 10^22 steps calc_jump:27.389ms
mexp 19937 jump 10^22 steps SFMT_jump: 3.283ms

並列生成サンプル

アーカイブに同梱されている sample1.cファイルは、 SFMT1279を使って、1020 ステップのジャンプをすることによって、重なりのないことが保証された部分列を5個生成 しています。5個のSFMTが1020以下の疑似乱数を生成する限り、 部分列が重なることはありません。

大きめのジャンプステップを指定して、重なりのない部分列を生成することが ジャンプ機能の重要な目的ですが、 ジャンプ機能を使って、並列にひとつながりの疑似乱数列を生成することも出来ます。 sample2.cでは6個のSFMT607を使用して ひとつながりの疑似乱数列を生成し、 ひとつのSFMT607で順次生成した疑似乱数列と比較しています。
このサンプルでは、順次生成と比較するために、小さなジャンプステップを使って いますが、実際にひとつながりの疑似乱数列を並列生成するなら、もっと大きな ジャンプステップを使用することになるはずです。

ライセンス

SFMT-jump は SFMT と同様に商用にも利用することができます。
詳細はLICENSE.txt を参照してください。