TinyMT の使い方メモ

Mersenne Twister の Tiny 版 TinyMT を調べたのでまとめておきます。

事前準備

パラメータを生成するために NTL というライブラリが必要です。今回は Ubuntu で行うのでライブラリがインストールされているかどうか確認して、なければ apt-get でインストールします。

$ dpkg -l | grep libntl

インストールは以下のように行います。

$ sudo apt-get install libntl-dev

パラメータ生成

ソースコードのダウンロードからパラメータ生成までは、以下のように行います。

$ mkdir temp
$ cd temp
$ wget -c http://www.math.sci.hiroshima-u.ac.jp/~m-mat/bin/dl/dl.cgi?TINY:TinyMT-src-1.0.1.tar.gz -O TinyMT-src-1.0.1.tar.gz
$ tar xf TinyMT-src-1.0.1.tar.gz
$ cd TinyMT-src-1.0.1/dc/src
$ make
$ ./tinymt32dc 9999

これで TinyMT を使用する際のパラメータが生成できました。以下のように出力されるはずです。

# charactristic, type, id, mat1, mat2, tmat, weight, delta
c8dc0f3cb047508416ca6c421edc9977,32,9999,f50a39ae,ffa8ffeb,65f37fff,59,0

この中の mat1、mat2、tmat を使用します。

動作確認

以下のテストプログラムを ~/temp/test.c に保存して動作確認します。

#include <stdio.h>
#include <time.h>
#include "tinymt32.h"

int main(int argc, char *argv[]) {
    tinymt32_t tinymt; // パラメータと状態を保持する構造体。サイズが 28 バイトしかないのでまさに Tiny
    tinymt.mat1 = 0xf50a39ae; // TinyMTDC で生成したパラメータ
    tinymt.mat2 = 0xffa8ffeb; // TinyMTDC で生成したパラメータ
    tinymt.tmat = 0x65f37fff; // TinyMTDC で生成したパラメータ
    tinymt32_init(&tinymt, (uint32_t) time(NULL)); // 初期化時に第二引数に seed を与えることで毎回異なる乱数を生成可能
    for (int i = 0; i < 10; i++) {
        printf("%08x\n", tinymt32_generate_uint32(&tinymt));
    }
    return 0;
}
$ cd ~/temp
$ gcc test.c TinyMT-src-1.0.1/tinymt/tinymt32.c -ITinyMT-src-1.0.1/tinymt -std=c99 
$ ./a.out

まとめ

僕の理解では、疑似乱数生成機とパラメータ生成機で実装が分かれているのは、疑似乱数生成機を小さく・軽く・速くするためなんだろうと思います。パラメータ生成機で作成したパラメータをプログラムにハードコードするのはどうなんだろう、と躊躇するわけですが、動的にパラメータを生成するとなると生成器が分かれている意味がなく、また NTL をリンクしなければならないため、組み込み用途などには向かなくなります。

MT と TinyMT の特徴は以下のようになっています。

疑似乱数生成機 メモリ 乱数周期
MT 2MB以上 2^19937-1
TinyMT 28 バイト 2^127-1

MT は疑似乱数の周期が天文学的数値ではあるのですが、メモリ使用量的に厳しいという環境もあるかもしれません。TinyMT の乱数周期で足りるのならば検討してみてもよいのかもしれません。