MT による疑似乱数生成器(C Version)
本編は、
- 疑似乱数生成のアルゴリズムを MT(Mersenne Twister) を利用
- プログラミング言語として C 言語を利用
したソースコードについて記載されています。
から構成されます。
I. 概要
MT(Mersenne Twister) で疑似乱数を生成します。
用途に応じたビット数の疑似乱数の生成
や、疑似乱数生成器の状態の保存・復元
を比較的容易に行えます。
構成は、ANSI 標準関数に置き換えて考えると分かり易いかもしれません。
既存のソースコードの srand 関数、rand 関数を置き換えると、
疑似乱数生成器を MT に置き換えたことになります。
II. 利用方法
nc_mtrandom.c をコンパイルし、生成されたオブジェクトファイルをターゲットモジュールにリンクします。
関数のプロトタイプは、nc_mtrandom.h で宣言されています。利用するソースコードにこれをインクルードします。
III. 関数リファレンス
以下、関数仕様のリファレンスです。
関数は、大きく 3 種類に分類されます。
- 疑似乱数生成器の初期化
- 疑似乱数の取得
- 疑似乱数生成器の状態の入出力
i. FncMtSrand
-
プロトタイプ
-
void FncMtSrand(unc_32_t uSeed);
-
機能
-
疑似乱数生成器に初期値を与えます。
初期値のデフォルトは、19650218 です。
引数 uSeed に 19650218 を与えると、
デフォルトの状態に再初期化されます。
-
戻り値
-
なし。
-
引数
-
-
uSeed
-
疑似乱数生成器に与える初期値。
ii. FncMtSrands
-
プロトタイプ
-
void FncMtSrands(cunc_32_t auSeed, unc_32_t uSeeds);
-
機能
-
疑似乱数生成器に uSeeds 個の初期値を与えます。
乱数の多様性が 0xffffffffh(4294967295) 個で足りない場合に利用します。
-
戻り値
-
なし。
-
引数
-
-
auSeed
-
疑似乱数生成器に与える初期値の配列。
-
uSeeds
-
疑似乱数生成器に与える初期値の配列数。
iii. FncMtRandomize
-
プロトタイプ
-
void FncMtRandomize(void);
-
機能
-
疑似乱数生成器に適当な初期値を与えます。
実装は time 関数の戻り値を疑似乱数生成器に与える初期値としています。
-
戻り値
-
なし。
-
引数
-
なし。
iv. FncMtRand
-
プロトタイプ
-
unc_32_t FncMtRand(void);
-
機能
-
0 から FFFFFFFFh(4294967295) の範囲内の疑似乱数(32 ビット符号なし整数値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
FncMtRandU32 関数のシノニムです。
-
戻り値
-
0 から FFFFFFFFh(4294967295) の範囲内の疑似乱数(32 ビット符号なし整数値)。
-
引数
-
なし。
v. FncMtRandU8
-
プロトタイプ
-
unc_8_t FncMtRandU8(void);
-
機能
-
0 から FFh(255) の範囲内の疑似乱数(8 ビット符号なし整数値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
-
戻り値
-
0 から FFh(255) の範囲内の疑似乱数(8 ビット符号なし整数値)。
-
引数
-
なし。
vi. FncMtRandU16
-
プロトタイプ
-
unc_16_t FncMtRandU16(void);
-
機能
-
0 から FFFFh(65535) の範囲内の疑似乱数(16 ビット符号なし整数値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
-
戻り値
-
0 から FFFFh(65535) の範囲内の疑似乱数(16 ビット符号なし整数値)。
-
引数
-
なし。
vii. FncMtRandU32
-
プロトタイプ
-
unc_32_t FncMtRandU32(void);
-
機能
-
0 から FFFFFFFFh(4294967295) の範囲内の疑似乱数(32 ビット符号なし整数値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
FncMtRand 関数のシノニムです。
-
戻り値
-
0 から FFFFFFFFh(4294967295) の範囲内の疑似乱数(32 ビット符号なし整数値)。
-
引数
-
なし。
viii. FncMtRandU64
-
プロトタイプ
-
unc_64_t FncMtRandU64(void);
-
機能
-
0 から FFFFFFFFFFFFFFFFh(18446744073709551615) の範囲内の疑似乱数(64 ビット符号なし整数値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
-
戻り値
-
0 から FFFFFFFFFFFFFFFFh(18446744073709551615) の範囲内の疑似乱数(64 ビット符号なし整数値)。
-
引数
-
なし。
ix. FncMtRandR32
-
プロトタイプ
-
rnc_32_t FncMtRandR32(void);
-
機能
-
0 から 1 未満(U32_TO_R32_LT_1*0xFFFFFFFFh)の範囲内の疑似乱数(32 ビット浮動小数点値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
-
戻り値
-
0 から 1 未満の範囲内の疑似乱数(32 ビット浮動小数点値)。
-
引数
-
なし。
x. FncMtRandR64
-
プロトタイプ
-
rnc_64_t FncMtRandR64(void);
-
機能
-
0 から 1 未満(U32_TO_R64_LT_1*0xFFFFFFFFh)の範囲内の疑似乱数(64 ビット浮動小数点値)を返します。
必要があれば FncMtSrand 関数、若しくは FncMtRandomize 関数を使って、
疑似乱数生成器を初期化します。
-
戻り値
-
0 から 1 未満の範囲内の疑似乱数(64 ビット浮動小数点値)。
-
引数
-
なし。
xi. FncMtSerialIn
-
プロトタイプ
-
int FncMtSerialIn(int iFdIn);
-
機能
-
FncMtSerialOut 関数によって出力された疑似乱数生成器の状態をシリアルに入力し復元します。
-
戻り値
-
エラーが発生すると 0 未満。
-
引数
-
-
iFdIn
-
入力用にオープンされたファイルディスクリプタ。
xii. FncMtSerialOut
-
プロトタイプ
-
int FncMtSerialOut(int iFdOut);
-
機能
-
現在の疑似乱数生成器の状態をシリアルに出力します。
出力の内容は、FncMtSerialIn 関数によって復元します。
-
戻り値
-
エラーが発生すると 0 未満。
-
引数
-
-
iFdOut
-
出力用にオープンされたファイルディスクリプタ。
xiii. FncMtSerialInFile
-
プロトタイプ
-
int FncMtSerialInFile(char const* pszFileName);
-
機能
-
FncMtSerialOutFile 関数によって出力された疑似乱数生成器の状態が保存されたファイルを入力し復元します。
-
戻り値
-
エラーが発生すると 0 未満。
-
引数
-
-
pszFileName
-
入力するファイル名。
xiv. FncMtSerialOutFile
-
プロトタイプ
-
int FncMtSerialOutFile(char const* pszFileName);
-
機能
-
現在の疑似乱数生成器の状態をファイルに出力します。
出力されたファイルの内容は、FncMtSerialInFile 関数によって復元します。
-
戻り値
-
エラーが発生すると 0 未満。
-
引数
-
-
pszFileName
-
出力するファイル名。
IV. ソースコードの信憑性
以下のコンパイラでそれぞれコンパイルを行い、
動作確認を行いました。
テスト方法は、
デバッグライトと mt19937int.out.txt の diff による比較に基づいて行いました。
そのデバッグライトは、main.c に記述されています。
- gcc version 2.95.3-5 (cygwin special)
- Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
- Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
V. 参考
M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.